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()
後的代碼影響不到最終結果