整个核心功能在于 compose,这个用于压缩所有被 use 调用过的中间件之上。每一次 use 一个新的中间件的时候,将其 push 进对象里边的成员变量 middlewares 当中。
所以重点就是要在 compose 当中进行递归,以合成最终要调用的那个函数,在监听到 request 请求的时候,将上下文对象 context 传入其中,最终完成整个所有中间件按照 洋葱圈
的模型去执行。
既然要用到递归,那就要先找到它的出口,也就是当 middlewares 数组合成到最后一个中间件的时候,直接返回:
Promise.resolve()
其他的情况,列出相应的关系式子,dispatch(i) 的执行结果返回的就是:
Promise.resolve(fn(context, function next() {
return dispatch(i + 1)
}))
因为涉及到 async、await 的语法以及相关的移步操作,所以上述递归的返回值都经过了 Promise 包装。
又由于最终要返回一个可接收上下文参数 context 的函数,所以还需要对 dispatch 进行进一步的包装,因此最终的 compose 如下所示:
compose(middlewares) {
return function (context) {
return dispatch(0)
function dispatch(i) {
let fn = middlewares[i]
if (!fn) {
return Promise.resolve()
}
return Promise.resolve(fn(context, function next() {
return dispatch(i + 1)
}))
}
}
}
相应的 use 就可以很快写出了:
use(callback) {
this.middlewares.push(callback)
}