koa的中间件执行流程像洋葱模型,和express的中间件执行顺序很不一样,express:middlewares数组一次popup出,知道执行到最后一个中间件,中间只要有response 返回,就中断next;而koa1的中间件是由generator组成的,执行顺序:从第一个中间件开始,遇到next进入下一个中间件,一直到最后一个中间件,再逆序执行直到第一个中间件
koa1的中间件
前提知识:如下的代码执行 执行next的时候遇到yield * foo()将foo generator委托,最终执行 打印出如下:
|
|
koa1的中间件列子:
|
|
其内部原理是:每次use的时候将gen放于middleware数组中,并且通过koa-compose
, co
库将这些中间组成fn, 然后没来一个请求都会讲fn作为回调函数来处理请求;
具体代码为:
可以看出来koa1的中间件是通过generator的消息委托机制来实现成洋葱模型,next参数就代表middleware中的下一个插件,通过yield next进入到下一个middleware;
koa2的中间件
koa2去除generator的方式,而已async wait的方式来实现中间件模式开发,每个中间件都是返回一个Promise的函数,并且每个Promise里都会有next()的调用来指代下一个中间件,列如:
|
|
async 中间件在koa2中的使用
也可以写成如下格式:
|
|
实现源码为:
|
|
原理分析:这里运用的是递归调用的方式实现中间件的洋葱模型和koa1很不太一样,一般在await next(), 而每次next执行的方法都会返回一个Promsie,await Promise 就是等待该Promise resolve返回,当然也可以通过外层的try catch来捕获Promise的reject信息;这样子只要中间有一个reject的promise直接返回Promise.reject(err)不去执行dispatch(i+1)这样子就不递归下去了;否则会一直递归到最后一个中间件