理解Koa洋葱模型
下面这段代码:
const Koa = require("koa");
const app = new Koa();
app.use( (ctx, next) => {
console.log(1);
next();
console.log(2);
});
app.use( (ctx, next) => {
console.log(3);
next();
console.log(4);
});
app.use( (ctx, next) => {
console.log(5);
next();
console.log(6);
});
app.listen(3000);
按照正常的逻辑输出的是:1,2,3,4,5,6;但是实际输出的是:
1,
3,
5,
6,
4,
2,
下面我们就来理解如何实现这种输出。
1.首先定义用来存函数的数组middlewares(中间件),定义用来将函数存入数组的函数use
const app = {
middlewares: [],// 用来存函数的数组
use: function (fn) {
this.middlewares.push(fn);
}
}
2.执行use函数,开始将use中的实参(函数)存入数组middlewares中
app.use((next) => {
console.log(1);
next();
console.log(2);
});
app.use((next) => {
console.log(3);
next();
console.log(4);
});
app.use((next) => {
console.log(5);
next();
console.log(6);
});
执行数组中的函数
// 定义compose函数
app.compose = function () {
return function () {
// 定义disPatch用来执行middlewares中的函数
function disPatch(idx) {
// 如果idx等于app.middlewares.length,则return掉
if (idx === app.middlewares.length) {
return;
}
// 从middlewares中取函数
const fn = app.middlewares[idx];
// 执行第一个app.use传入的实参(函数),并且传入实参next
fn(function next() {
disPatch(++idx);
});
}
// 传入0,开始执行middlewares中的第一个函数,即执行app.use中传入的第一个函数
disPatch(0);
};
};
app.compose()();
执行顺序:
next函数即下一个app.use中传入的函数;
第三个app.use的next函数,会因为idx等于app.middlewares.length直接return掉;
当4执行完,则表示第一个app.use中next函数已执行完;
所以会往下执行,执行2,执行完2,所有代码全部执行完成,
比如你手里有一支牙签,横向穿过一个洋葱,是不是会层层穿透?从第一层进去、到第二层、第三次…然后到中间层后,再层层穿透的出,从第三层出、第二层、第一层…。就是koa的洋葱模型,一个执行顺序