中間件用法——講解 Koa2 中間件的用法及如何開發(fā)中間件
???? iKcamp 制作團(tuán)隊(duì)
原創(chuàng)作者:大哼、阿干蒋腮、三三淘捡、小虎、胖子池摧、小哈焦除、DDU、可木作彤、晃晃
文案校對(duì):李益膘魄、大力萌乌逐、Au、DDU创葡、小溪里浙踢、小哈
風(fēng)采主播:可木、阿干灿渴、Au洛波、DDU、小哈
視頻剪輯:小溪里
主站運(yùn)營:給力xi骚露、xty
教程主編:張利濤
視頻地址:https://www.cctalk.com/v/15114357763623
文章
middleware 中間件
正是因?yàn)橹虚g件的擴(kuò)展性才使得
Koa
的代碼簡單靈活蹬挤。
在 app.js
中,有這樣一段代碼:
app.use(async (ctx, next)=>{
await next()
ctx.response.type = 'text/html'
ctx.response.body = '<h1>Hello World</h1>'
})
它的作用是:每收到一個(gè) http
請(qǐng)求棘幸,Koa
都會(huì)調(diào)用通過 app.use()
注冊(cè)的 async
函數(shù)闻伶,同時(shí)為該函數(shù)傳入 ctx
和 next
兩個(gè)參數(shù)。而這個(gè) async
函數(shù)就是我們所說的中間件够话。
下面我們簡單介紹一下傳入中間件的兩個(gè)參數(shù)蓝翰。
ctx
ctx
作為上下文使用,包含了基本的 ctx.request
和 ctx.response
女嘲。另外畜份,還對(duì) Koa
內(nèi)部對(duì)一些常用的屬性或者方法做了代理操作,使得我們可以直接通過 ctx
獲取欣尼。比如爆雹,ctx.request.url
可以寫成 ctx.url
。
除此之外愕鼓,Koa
還約定了一個(gè)中間件的存儲(chǔ)空間 ctx.state
钙态。通過 state
可以存儲(chǔ)一些數(shù)據(jù),比如用戶數(shù)據(jù)菇晃,版本信息等册倒。如果你使用 webpack
打包的話,可以使用中間件磺送,將加載資源的方法作為 ctx.state
的屬性傳入到 view
層驻子,方便獲取資源路徑。
next
next
參數(shù)的作用是將處理的控制權(quán)轉(zhuǎn)交給下一個(gè)中間件估灿,而 next()
后面的代碼崇呵,將會(huì)在下一個(gè)中間件及后面的中間件(如果有的話)執(zhí)行結(jié)束后再執(zhí)行。
注意: 中間件的順序很重要馅袁!
我們重寫 app.js
來解釋下中間件的流轉(zhuǎn)過程:
// 按照官方示例
const Koa = require('koa')
const app = new Koa()
// 記錄執(zhí)行的時(shí)間
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(`請(qǐng)求地址: ${ctx.path}域慷,響應(yīng)時(shí)間:${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')
})
運(yùn)行起來后,控制臺(tái)顯示:
server is running at http://localhost:3000
然后打開瀏覽器,訪問 http://localhost:3000
犹褒,控制臺(tái)顯示內(nèi)容更新為:
server is running at http://localhost:3000
中間件1 doSoming
中間件2 doSoming
中間件3 doSoming
中間件3 end
中間件2 end
中間件1 end
請(qǐng)求地址: /兄纺,響應(yīng)時(shí)間:2ms
從結(jié)果上可以看到,流程是一層層的打開化漆,然后一層層的閉合估脆,像是剝洋蔥一樣 —— 洋蔥模型。
此外座云,如果一個(gè)中間件沒有調(diào)用 await next()
疙赠,會(huì)怎樣呢?答案是『后面的中間件將不會(huì)執(zhí)行』朦拖。
修改 app.js
如下圃阳,我們?nèi)サ袅说谌齻€(gè)中間件里面的 await
:
const Koa = require('koa')
const app = new Koa()
// 記錄執(zhí)行的時(shí)間
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(`請(qǐng)求地址: ${ctx.path},響應(yīng)時(shí)間:${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')
})
重新運(yùn)行代碼后捍岳,控制臺(tái)顯示如下:
server is running at http://localhost:3000
中間件1 doSoming
中間件2 doSoming
中間件2 end
中間件1 end
請(qǐng)求地址: /,響應(yīng)時(shí)間:1ms
與我們的預(yù)期結(jié)果『后面的中間件將不會(huì)執(zhí)行』是一致的睬隶。
下一篇:我們將學(xué)習(xí)下如何響應(yīng)瀏覽器的各種請(qǐng)求锣夹。
上一篇:iKcamp新課程推出啦~~~~~iKcamp團(tuán)隊(duì)制作|基于Koa2搭建Node.js實(shí)戰(zhàn)(含視頻)? 環(huán)境準(zhǔn)備