刚才翻了下Koa源码,看了compose实现有些疑问
来源:11-11 中间件原理-代码演示
西岚Silan
2020-03-19
function compose (middleware) {
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}
/**
* @param {Object} context
* @return {Promise}
* @api public
*/
return function (context, next) {
// last called middleware #
console.log(context)
let index = -1
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i
let fn = middleware[i]
if (i === middleware.length) fn = next // 这行代码是啥意思,
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}我很奇怪的就是 24行代码 为啥要在递归执行完所有中间件后, i === 中间件数组长度,也就是没有中间件可以在执行时,
next会赋值给fn, 我调试的时候发现,他们都是undefined,啥情况才不会是undefiend?
另外一提,我感觉无论是回调还是递归,本质还跟js执行栈和异步队列有关系,老的中间件进栈,执行dispatch,把promise.resolve()里面的中间件推进异步队列,然后队列遵循先进先出的原则,这个新的中间件就退出队列,进入执行栈,然后出栈,最后才是上一个中间件出栈
写回答
2回答
-
双越
2020-03-20
看了下,我也没太看懂这一行。无所谓,甭管它,毕竟是源码的一些细节,不妨碍我们对 koa2 中间件的理解。
PS:你贴的代码没折行,我眼睛都快看瞎了~
10 -
Inuyasha__
2020-04-03
看了一下代码,
1:应该是作为一个中间件的桥梁的作用,next里面可以包含另一个compose生成的函数,大概就是实现一个链式调用,即第一个compose生成的函数全部调用完且成功会调用第二个compose生成的函数:
2:next也可以传一个函数,相当于finally,当整个koa2的中间件函数执行后,可以执行这个函数
00