express
和 koa
中间件是用于处理 http
请求和响应的,但是二者的设计思路确不尽相同。
express
中间件一个接一个的顺序执行, 习惯于将response
响应写在最后一个中间件中;
而koa
的中间件执行顺序是“洋葱圈”模型。
其实中间件也是一种拦截器的思想
我们先看下express中间件的执行顺序
得到的结果是
下面是koa中间件执行顺序
const Koa = require('koa');
const app = new Koa();
app.use(async (ctx, next) => {
console.log('1111');
await next(); // 调用下一个middleware
console.log('2222');
});
app.use(async (ctx, next) => {
console.log('333');
await next();
console.log('444');
});
app.use(async (ctx, next) => {
await next();
console.log('555');
});
app.listen(3003);
console.log('app started at port 3000...');
我们知道当一个中间件调用 next() 该函数的时候会暂停并将控制传递给定义的下一个中间件。
当在下游没有更多的中间件执行后,将会恢复执行其上游的中间件
运行的结果是:
app started at port 3000...
1111
333
555
444
2222
结果原因是当我们运行第一个中间件的时候打印出'111'此时 改中间件暂停将控制权交给
第二个中间件函数,在此说明中间件的执行顺序很重要在具体业务中有的中间件要提前定义
第二个中间件的时候打印出'333'此时 中间件暂停将控制权交给第3个中间件函数,
在第三个中间件的时候没有先打印直接调用
await next();
但是没有其他中间件下游没有更多的中间件执行后,将会恢复执行其上游的中间件
但是会先打印出555因为这段打印代码也包含在最后一个中间件里面会先执行 以此向上一个执行打印出 444 在向上一个执行打印出222 相当于栈先进后出
如果我们改变一下最后一个中间件
app.use(async (ctx, next) => {
//await next(); //注释这行
console.log('555');
});
打印结果一样是:
app started at port 3000...
1111
333
555
444
2222
最后得出的结果两者都是相同的
所以实际上,express
的中间件也可以形成“洋葱圈”模型,在 next
调用后写的代码同样会执行到,只不过express
中一般不会这么做,因为 express
的response
一般在最后一个中间件,所以其它中间件 next()
后的代码影响不到最终结果