koa-compose源码解析

介绍

Compose middleware.

compose 函数是 koa 洋葱模型的核心,作为一个 koa 中间件使用,他会创建返回一个递归函数,借由每个中间件的 next 调用 dispatch、传递 context,不断改变内存中的 index 索引,进而做出终止判断。

不难看出,这是闭包的一种使用方式,index 和 dispatch 保存在内存中便于后续调用。

源码 koa-compose 4.1.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
function compose(middleware) {
// 判断middleware是否数组,其内容是否为function类型
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!");
}

return function (context, next) {
// 当前调用的middleware索引
let index = -1;
// 调用dispatch,开始进入"洋葱模型"
return dispatch(0);
// dispatch属于闭包存在内存中,便于后续调用next()
function dispatch(i) {
// 判断index,防止多次调用next
if (i <= index)
return Promise.reject(new Error("next() called multiple times"));
// 更新index索引
index = i;
// 依次读取middleware中的function
let fn = middleware[i];
// 遍历到最后一项,next赋值给fn,此时为undefined,然后resolve跳出
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve();
try {
// 包装成promise,返回调用下一个中间件
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
// 捕获错误
return Promise.reject(err);
}
}
};
}

参考链接

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

给阿姨来一杯卡普基诺~

支付宝
微信