iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 中介軟體用法

iKcamp發表於2017-12-22

中介軟體用法——講解 Koa2 中介軟體的用法及如何開發中介軟體

?? iKcamp 製作團隊

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


視訊地址:www.cctalk.com/v/151143577…

iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 中介軟體用法

文章

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 函式,同時為該函式傳入 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 來解釋下中介軟體的流轉過程:

// 按照官方示例
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團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 中介軟體用法

iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 中介軟體用法

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

推薦: 翻譯專案Master的自述:

乾貨|人人都是翻譯專案的Master


iKcamp團隊製作|基於Koa2搭建Node.js實戰(含視訊)☞ 中介軟體用法

2019年,iKcamp原創新書《Koa與Node.js開發實戰》已在京東、天貓、亞馬遜、噹噹開售啦!

相關文章