刚才翻了下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:你贴的代码没折行,我眼睛都快看瞎了~

1
0

Inuyasha__

2020-04-03

看了一下代码,

1:应该是作为一个中间件的桥梁的作用,next里面可以包含另一个compose生成的函数,大概就是实现一个链式调用,即第一个compose生成的函数全部调用完且成功会调用第二个compose生成的函数:

2:next也可以传一个函数,相当于finally,当整个koa2的中间件函数执行后,可以执行这个函数

0
0

Node.js+Express+Koa2+Nest.js 开发服务端

从入门到实战,一站式掌握 Node.js+Express+Koa2

4049 学习 · 2006 问题

查看课程