广义中间件

前言

  • 不直接提供中间件
  • 通过间接方式提供了中间件,最常见的是间接中间件子中间件
  • 间接被 app.use() 加载
  • 其他方式接入Koa切面

间接中间件

  1. const Koa = require('koa');
  2. let app = new Koa();
  3. function indirectMiddleware(path, middleware) {
  4. return async function(ctx, next) {
  5. console.log(ctx.path === path, middleware);
  6. if (ctx.path === path) {
  7. await middleware(ctx, next);
  8. } else {
  9. await next();
  10. }
  11. };
  12. }
  13. const index = async function(ctx, next) {
  14. ctx.body = 'this is index page';
  15. };
  16. const hello = async function(ctx, next) {
  17. ctx.body = 'this is hello page';
  18. };
  19. const world = async function(ctx, next) {
  20. ctx.body = 'this is world page';
  21. };
  22. app.use(indirectMiddleware('/', index));
  23. app.use(indirectMiddleware('/hello', hello));
  24. app.use(indirectMiddleware('/world', world));
  25. app.listen(3001, () => {
  26. console.log('the demo is start at port 3001');
  27. });

子中间件

子中间件是广义中间件的一个最有代表场景,主要的特点有

  • 初始化中间件时,内置子中间件列表
  • 子中间件列表添加子中间件元素
  • 子中间件列表封装成间接中间件,让后被app.use()加载
  1. const Koa = require('koa');
  2. let app = new Koa();
  3. class Middleware{
  4. constructor() {
  5. this.stack = [];
  6. }
  7. get(path, childMiddleware) {
  8. this.stack.push({ path, middleware: childMiddleware })
  9. }
  10. middlewares() {
  11. let stack = this.stack;
  12. return async function(ctx, next) {
  13. let path = ctx.path;
  14. for( let i=0; i<stack.length; i++ ) {
  15. const child = stack[i];
  16. if( child && child.path === path && child.middleware ) {
  17. await child.middleware(ctx, next);
  18. }
  19. }
  20. await next();
  21. }
  22. }
  23. }
  24. const middleware = new Middleware();
  25. middleware.get('/page/001', async(ctx, next) => { ctx.body = 'page 001' })
  26. middleware.get('/page/002', async(ctx, next) => { ctx.body = 'page 002' })
  27. middleware.get('/page/003', async(ctx, next) => { ctx.body = 'page 003' })
  28. app.use(middleware.middlewares());
  29. app.listen(3001, function(){
  30. console.log('the demo is start at port 3001');
  31. })