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

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

?? iKcamp 製做團隊

原創做者:大哼阿幹三三小虎胖子小哈DDU可木晃晃
文案校對:李益大力萌AuDDU小溪裏小哈
風采主播:可木阿幹AuDDU小哈
視頻剪輯:小溪裏
主站運營:給力xixty
教程主編:張利濤html


視頻地址:https://www.cctalk.com/v/15114357763623webpack

文章

middleware 中間件

正是由於中間件的擴展性才使得 Koa 的代碼簡單靈活。

app.js 中,有這樣一段代碼:git

app.use(async (ctx, next)=>{
  await next()
  ctx.response.type = 'text/html'
  ctx.response.body = '<h1>Hello World</h1>'  
})

它的做用是:每收到一個 http 請求,Koa 都會調用經過 app.use() 註冊的 async 函數,同時爲該函數傳入 ctxnext 兩個參數。而這個 async 函數就是咱們所說的中間件。github

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

ctx

ctx 做爲上下文使用,包含了基本的 ctx.requestctx.response。另外,還對 Koa 內部對一些經常使用的屬性或者方法作了代理操做,使得咱們能夠直接經過 ctx 獲取。好比,ctx.request.url 能夠寫成 ctx.url瀏覽器

除此以外,Koa 還約定了一箇中間件的存儲空間 ctx.state。經過 state 能夠存儲一些數據,好比用戶數據,版本信息等。若是你使用 webpack 打包的話,能夠使用中間件,將加載資源的方法做爲 ctx.state 的屬性傳入到 view 層,方便獲取資源路徑。app

next

next 參數的做用是將處理的控制權轉交給下一個中間件,而 next() 後面的代碼,將會在下一個中間件及後面的中間件(若是有的話)執行結束後再執行。koa

注意: 中間件的順序很重要! async

咱們重寫 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

相關文章
相關標籤/搜索