美文网首页
Koa项目总结二:Koa中间件的理解

Koa项目总结二:Koa中间件的理解

作者: joyitsai | 来源:发表于2019-05-20 17:00 被阅读0次

    1. 中间件的概念:

    先看下面一段代码:

    app.use(async (ctx, next)=>{
        console.log(ctx.method, ctx.host+ctx.url);//打印请求方法、主机名、URL
        await next();
        ctx.body = 'Hello World';
    })
    

    上面的代码是Koa应用程序的一个简单的'Hello World'示例,可以把其中打印日志的部分单独抽象成一个logger函数:

    const logger = async (ctx, next)=>{
        console.log(ctx.method, ctx.host+ctx.url);
        await next();
    }
    app.use(logger);
    app.use(async (ctx, next)=>{
        ctx.body = 'Hello World';
    })
    

    抽象出来的logger函数就是中间件。
    简单的说,通过app.use()、router.get()和router.post()等调用的功能函数,就是中间件。中间件主要有四大类:

    1.1 app.use()调用的,应用级中间件:
    const Koa = require('koa');
    const router = require('koa-router')();
    const app = new Koa();
    
    /**应用级中间件*/
    app.use(async (ctx,next)=>{
      console.log(ctx.method, ctx.host+ctx.url);
      await next();
    })
    router.get('/', function (ctx, next) {
      ctx.body="Hello koa";
    })
    router.get('/news',(ctx,next)=>{
      ctx.body="新闻页面"
    });
    app.use(router.routes()); //作用:启动路由
    app.use(router.allowedMethods()); //作用: 当请求出错时的处理逻辑
    app.listen(3000,()=>{
      console.log('starting at port 3000');
    });
    

    应用级中间件,通过任何URL请求,都会先匹配到。也就是说,上面这段代码,在通过localhost:3000localhost:3000/news访问时,都会先经过应用级中间件,先打印出请求的方法、主机名和url,再向下匹配路由,通过router.get()匹配路由后调用的中间件是路由级中间件。

    1.2 路由级中间件:

    再上面的代码段中,通过router.getrouter.post匹配的路由调用的函数,称之为路由级中间件:

    router.get('/', function (ctx, next) {
      ctx.body="Hello koa";
    })
    router.get('/news',(ctx,next)=>{
      ctx.body="新闻页面"
    });
    

    在应用级中间件执行完成后,通过await next()将执行权限移交给下一级中间件,此时开始向下匹配路由,执行路由级中间件。

    1.3 错误处理中间件:
    app.use(async (ctx,next)=> {
      await next();
      if(ctx.status==404){
        ctx.status = 404;
        ctx.body="这是一个404 页面"
      }
    });
    
    1.4 app.use()调用,第三方中间件:
    const static = require('koa-static');
    const staticPath = './static';
    app.use(static(
      path.join( __dirname, staticPath)
    ))
    const bodyParser = require('koa-bodyparser');
    /*调用第三方中间件bodyParser()*/
    app.use(bodyParser());
    
    • 中间件函数是一个带有ctxnext两个参数的简单函数(对于第三方中间件,ctx和next已经被封装在内部了)
    • next用于把中间件的执行权限交给下游中间件(await next()是因为next()返回的是一个Promise对象)
    • 而当前中间件中,位于next()之后的代码会暂停执行,直到最后一个中间件执行完毕,再自下而上依次执行每个中间件中next()之后的代码,类似于一种先进后出的堆栈结构。
    • 官方给出的洋葱模型示意图,来解释中间件的执行顺序:
      洋葱模型示意图

    2. Koa中间件执行顺序:

    根据上面对于中间件执行顺序的解释,我们通过一段代码测试一下:

    app.use(async (ctx, next)=>{
        console.log('1 start');
        await next();
        console.log('1 end');
    })
    app.use(async (ctx, next)=>{
        console.log('2 start');
        await next();
        console.log('2 end');
    });
    router.get('/test', async (ctx, next)=>{
        console.log('3 start');
        ctx.body = 'Hello Koa'
        await next();
        console.log('3 end');
    })
    

    控制台输出的结果是:

    1 start
    2 start
    3 start
    3 end
    2 end
    1 end
    

    由此验证了Koa中间件的执行顺序,先自上而下执行await next()之前的代码,当最后一个中间件执行完成后,再自下而上执行await next()之后的代码。
    反观1.3 错误处理中间件中的代码,就是利用了匹配完所有路由后,再对最终ctx.status为404的请求返回404页面

    相关文章

      网友评论

          本文标题:Koa项目总结二:Koa中间件的理解

          本文链接:https://www.haomeiwen.com/subject/eiukzqtx.html