iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視頻)? 中間件用法

中間件用法——講解 Koa2 中間件的用法及如何開發中間件

???? iKcamp 製作團隊

原創作者:大哼、阿干、三三、小虎、胖子、小哈、DDU、可木、晃晃

文案校對:李益、大力萌、Au、DDU、小溪里、小哈

風采主播:可木、阿干、Au、DDU、小哈

視頻剪輯:小溪里

主站運營:給力xi、xty

教程主編:張利濤


滬江CCtalk視頻地址:cctalk.com/v/1511435776

文章

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 函數,同時為該函數傳入 ctxnext 兩個參數。而這個 async 函數就是我們所說的中間件。

下面我們簡單介紹一下傳入中間件的兩個參數。

ctx

ctx 作為上下文使用,包含了基本的 ctx.requestctx.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

與我們的預期結果『後面的中間件將不會執行』是一致的。

下一篇:我們將學習下如何響應瀏覽器的各種請求。

weixin.qq.com/r/MjoLExL (二維碼自動識別)

上一篇:iKcamp新課程推出啦~~~~~iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視頻)? 環境準備

推薦: 翻譯項目Master的自述:

乾貨|人人都是翻譯項目的Master

推薦閱讀:

Koa 請求日誌打點工具(三)—— OpenTracing + Jaeger
Egg + Webpack 熱更新實現
iKcamp|基於Koa2搭建Node.js實戰(含視頻)? HTTP請求
為什麼Node的web端框架express和Koa的生態環境差距還是巨大(2017.11)?

TAG:前端开发 | Nodejs | koa |