koa2的中介軟體是通過async await
實現的,中介軟體執行順序是“洋蔥圈”模型。
中介軟體之間通過next函式聯絡,當一箇中介軟體呼叫next()
後,會將控制權交給下一個中介軟體, 直到下一個中介軟體不再執行next()
後, 將會沿路折返,將控制權依次交換給前一箇中介軟體。
如圖:
const koa = require('koa');
// logger
console.log('第一層 - 開始')
await next();
const rt = ctx.response.get('x-response-time');
console.log(`$ ----------- $ ----------- $`);
console.log('第一層 - 結束')
});// x-response-time
console.log('第二層 - 開始')
const start = date.now();
await next();
const ms = date.now() - start;
ctx.set('x-response-time', `$ms`);
console.log('第二層 - 結束')
});// response
console.log('第三層 - 開始')
ctx.body = 'hello world';
console.log('第三層 - 結束')
});
第一層 - 開始
第二層 - 開始
第三層 - 開始
第三層 - 結束
第二層 - 結束
列印第一次執行的結果: get -------- /text ------ 4ms
第一層 - 結束
下面是一個登陸驗證的中介軟體:
logincheck.js:
module.exports = async (ctx, next) =>
// 登陸失敗,禁止繼續執行,所以不需要執行 next()
ctx.body =
}
在刪除操作中使用 logincheck.js :
router.post('/delete', logincheck, async (ctx, next) =>
} else }})
與 koa2 中介軟體不同的是,express中介軟體一個接一個的順序執行, 通常會將 response 響應寫在最後一箇中介軟體中
遇到 http 請求,根據 path 和 method 判斷觸發哪些中介軟體
const express = require('express')
console.log('第一層 - 開始')
settimeout(() => , 0)
console.log('第一層 - 結束')
}) console.log('第二層 - 開始')
settimeout(() => , 0)
console.log('第二層 - 結束')
}) console.log('第三層 - 開始')
res.json()
console.log('第三層 - 結束')
}) console.log('server is running on port 3000')
})
第一層 - 開始
第一層 - 結束
第二層 - 開始
第二層 - 結束
第三層 - 開始
第三層 - 結束
因為上面各個中介軟體中的 next() 是非同步執行的,所以 列印結果是線行輸出的。
如果取消上面next()的非同步執行,直接按如下方式:
const express = require('express')
console.log('第一層 - 開始')
next()
console.log('第一層 - 結束')
}) console.log('第二層 - 開始')
next()
console.log('第二層 - 結束')
}) console.log('第三層 - 開始')
res.json()
console.log('第三層 - 結束')
}) console.log('server is running on port 3000')
})
第一層 - 開始
第二層 - 開始
第三層 - 開始
第三層 - 結束
第二層 - 結束
第一層 - 結束
可見,express 的中介軟體也可以形成“洋蔥圈”模型,但是一般在express中不會這麼做,因為 express 的 response 一般在最後一箇中介軟體,所以其它中介軟體 next() 後的**影響不到最終結果。
下面是一個登陸驗證的中介軟體:
logincheck.js:
module.exports = (req, res, next) =>
// 登陸失敗,禁止繼續執行,所以不需要執行 next()
ctx.body =
}
在刪除操作中使用 logincheck.js :
router.post('/delete', logincheck, (req, res, next) =>
} else }})
})