中介軟體用法——講解 Koa2 中介軟體的用法及如何開發中介軟體
?? iKcamp 製作團隊
原創作者:大哼、阿幹、三三、小虎、胖子、小哈、DDU、可木、晃晃
文案校對:李益、大力萌、Au、DDU、小溪裡、小哈
風采主播:可木、阿幹、Au、DDU、小哈
視訊剪輯:小溪裡
主站運營:給力xi、xty
教程主編:張利濤
視訊地址:www.cctalk.com/v/151143577…
文章
middleware 中介軟體
正是因為中介軟體的擴充套件性才使得
Koa
的程式碼簡單靈活。
在 app.js
中,有這樣一段程式碼:
app.use(async (ctx, next)=>{
await next()
ctx.response.type = 'text/html'
ctx.response.body = '<h1>Hello World</h1>'
})
複製程式碼
它的作用是:每收到一個 http
請求,Koa
都會呼叫通過 app.use()
註冊的 async
函式,同時為該函式傳入 ctx
和 next
兩個引數。而這個 async
函式就是我們所說的中介軟體。
下面我們簡單介紹一下傳入中介軟體的兩個引數。
ctx
ctx
作為上下文使用,包含了基本的 ctx.request
和 ctx.response
。另外,還對 Koa
內部對一些常用的屬性或者方法做了代理操作,使得我們可以直接通過 ctx
獲取。比如,ctx.request.url
可以寫成 ctx.url
。
除此之外,Koa
還約定了一箇中介軟體的儲存空間 ctx.state
。通過 state
可以儲存一些資料,比如使用者資料,版本資訊等。如果你使用 webpack
打包的話,可以使用中介軟體,將載入資源的方法作為 ctx.state
的屬性傳入到 view
層,方便獲取資源路徑。
next
next
引數的作用是將處理的控制權轉交給下一個中介軟體,而 next()
後面的程式碼,將會在下一個中介軟體及後面的中介軟體(如果有的話)執行結束後再執行。
注意: 中介軟體的順序很重要!
我們重寫 app.js
來解釋下中介軟體的流轉過程:
// 按照官方示例
const Koa = require('koa')
const app = new Koa()
// 記錄執行的時間
app.use(async (ctx, next) => {
let stime = new Date().getTime()
await next()
let etime = new Date().getTime()
ctx.response.type = 'text/html'
ctx.response.body = '<h1>Hello World</h1>'
console.log(`請求地址: ${ctx.path},響應時間:${etime - stime}ms`)
});
app.use(async (ctx, next) => {
console.log('中介軟體1 doSoming')
await next();
console.log('中介軟體1 end')
})
app.use(async (ctx, next) => {
console.log('中介軟體2 doSoming')
await next();
console.log('中介軟體2 end')
})
app.use(async (ctx, next) => {
console.log('中介軟體3 doSoming')
await next();
console.log('中介軟體3 end')
})
app.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})
複製程式碼
執行起來後,控制檯顯示:
server is running at http://localhost:3000
複製程式碼
然後開啟瀏覽器,訪問 http://localhost:3000
,控制檯顯示內容更新為:
server is running at http://localhost:3000
中介軟體1 doSoming
中介軟體2 doSoming
中介軟體3 doSoming
中介軟體3 end
中介軟體2 end
中介軟體1 end
請求地址: /,響應時間:2ms
複製程式碼
從結果上可以看到,流程是一層層的開啟,然後一層層的閉合,像是剝洋蔥一樣 —— 洋蔥模型。
此外,如果一箇中介軟體沒有呼叫 await next()
,會怎樣呢?答案是『後面的中介軟體將不會執行』。
修改 app.js
如下,我們去掉了第三個中介軟體裡面的 await
:
const Koa = require('koa')
const app = new Koa()
// 記錄執行的時間
app.use(async (ctx, next)=>{
let stime = new Date().getTime()
await next()
let etime = new Date().getTime()
ctx.response.type = 'text/html'
ctx.response.body = '<h1>Hello World</h1>'
console.log(`請求地址: ${ctx.path},響應時間:${etime - stime}ms`)
});
app.use(async (ctx, next) => {
console.log('中介軟體1 doSoming')
await next();
console.log('中介軟體1 end')
})
app.use(async (ctx, next) => {
console.log('中介軟體2 doSoming')
// 注意,這裡我們刪掉了 next
// await next()
console.log('中介軟體2 end')
})
app.use(async (ctx, next) => {
console.log('中介軟體3 doSoming')
await next();
console.log('中介軟體3 end')
})
app.listen(3000, () => {
console.log('server is running at http://localhost:3000')
})
複製程式碼
重新執行程式碼後,控制檯顯示如下:
server is running at http://localhost:3000
中介軟體1 doSoming
中介軟體2 doSoming
中介軟體2 end
中介軟體1 end
請求地址: /,響應時間:1ms
複製程式碼
與我們的預期結果『後面的中介軟體將不會執行』是一致的。
下一篇:我們將學習下如何響應瀏覽器的各種請求。
上一篇:iKcamp新課程推出啦~~~~~iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 環境準備
推薦: 翻譯專案Master的自述:
乾貨|人人都是翻譯專案的Master
2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!