iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視頻)? 中間件用法
中間件用法——講解 Koa2 中間件的用法及如何開發中間件
???? iKcamp 製作團隊
原創作者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃
文案校對:李益、大力萌、Au、DDU、小溪里、小哈 風采主播:可木、阿干、Au、DDU、小哈視頻剪輯:小溪里
主站運營:給力xi、xty 教程主編:張利濤滬江CCtalk視頻地址:https://www.cctalk.com/v/15114357763623
文章
middleware 中間件
正是因為中間件的擴展性才使得
Koa
的代碼簡單靈活。
在 app.js
中,有這樣一段代碼:
app.use(async (ctx, next)=>{n await next()n ctx.response.type = text/htmln ctx.response.body = <h1>Hello World</h1> n})n
它的作用是:每收到一個 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
來解釋下中間件的流轉過程:
// 按照官方示例nconst Koa = require(koa)nconst app = new Koa()nn// 記錄執行的時間napp.use(async (ctx, next) => {n let stime = new Date().getTime()n await next()n let etime = new Date().getTime()n ctx.response.type = text/htmln ctx.response.body = <h1>Hello World</h1>n console.log(`請求地址: ${ctx.path},響應時間:${etime - stime}ms`)n});nnapp.use(async (ctx, next) => {n console.log(中間件1 doSoming)n await next();n console.log(中間件1 end)n})nnapp.use(async (ctx, next) => {n console.log(中間件2 doSoming)n await next();n console.log(中間件2 end)n})nnapp.use(async (ctx, next) => {n console.log(中間件3 doSoming)n await next();n console.log(中間件3 end)n})nnapp.listen(3000, () => {n console.log(server is running at http://localhost:3000)n})n
運行起來後,控制台顯示:
server is running at http://localhost:3000n
然後打開瀏覽器,訪問 http://localhost:3000
,控制台顯示內容更新為:
server is running at http://localhost:3000n中間件1 doSomingn中間件2 doSomingn中間件3 doSomingn中間件3 endn中間件2 endn中間件1 endn請求地址: /,響應時間:2msn
從結果上可以看到,流程是一層層的打開,然後一層層的閉合,像是剝洋蔥一樣 —— 洋蔥模型。
此外,如果一個中間件沒有調用 await next()
,會怎樣呢?答案是『後面的中間件將不會執行』。
修改 app.js
如下,我們去掉了第三個中間件裡面的 await
:
const Koa = require(koa)nconst app = new Koa()nn// 記錄執行的時間napp.use(async (ctx, next)=>{n let stime = new Date().getTime()n await next()n let etime = new Date().getTime()n ctx.response.type = text/htmln ctx.response.body = <h1>Hello World</h1>n console.log(`請求地址: ${ctx.path},響應時間:${etime - stime}ms`)n});nnapp.use(async (ctx, next) => {n console.log(中間件1 doSoming)n await next();n console.log(中間件1 end)n})nnapp.use(async (ctx, next) => {n console.log(中間件2 doSoming)n // 注意,這裡我們刪掉了 nextn // await next()n console.log(中間件2 end)n})nnapp.use(async (ctx, next) => {n console.log(中間件3 doSoming)n await next();n console.log(中間件3 end)n})nnapp.listen(3000, () => {n console.log(server is running at http://localhost:3000)n})n
重新運行代碼後,控制台顯示如下:
server is running at http://localhost:3000n中間件1 doSomingn中間件2 doSomingn中間件2 endn中間件1 endn請求地址: /,響應時間:1msn
與我們的預期結果『後面的中間件將不會執行』是一致的。
下一篇:我們將學習下如何響應瀏覽器的各種請求。
http://weixin.qq.com/r/MjoLExLEsU-OrVZw928g (二維碼自動識別)
上一篇:iKcamp新課程推出啦~~~~~iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視頻)? 環境準備
推薦: 翻譯項目Master的自述:
乾貨|人人都是翻譯項目的Master
推薦閱讀:
※Koa 請求日誌打點工具(三)—— OpenTracing + Jaeger
※Egg + Webpack 熱更新實現
※iKcamp|基於Koa2搭建Node.js實戰(含視頻)? HTTP請求
※為什麼Node的web端框架express和Koa的生態環境差距還是巨大(2017.11)?