刚才翻了下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