摘要:當中間件運行時,它必須手動調用來運行下游中間件。例如,這個中間件從讀取文件名,然后在將給指定合并結果之前并行讀取每個文件的內容。當你無法控制中間件的名稱時,這很有用。
指南
此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star.
本指南涵蓋的 Koa 主題不與 API 直接相關,例如編寫中間件的最佳做法和應用程序結構建議。在這些例子中,我們使用 async 函數作為中間件 - 您也可以使用 commonFunction 或generatorFunction,這將些所不同。
編寫中間件Koa 中間件是簡單的函數,它返回一個帶有簽名 (ctx, next) 的MiddlewareFunction。當中間件運行時,它必須手動調用 next() 來運行 “下游” 中間件。
例如,如果你想要跟蹤通過添加 X-Response-Time 頭字段通過 Koa 傳播請求需要多長時間,則中間件將如下所示:
async function responseTime(ctx, next) { const start = Date.now(); await next(); const ms = Date.now() - start; ctx.set("X-Response-Time", `${ms}ms`); } app.use(responseTime);
如果您是前端開發人員,您可以將 next(); 之前的任意代碼視為“捕獲”階段,這個簡易的 gif 說明了 async 函數如何使我們能夠恰當地利用堆棧流來實現請求和響應流:
創建一個跟蹤響應時間的日期
等待下一個中間件的控制
創建另一個日期跟蹤持續時間
等待下一個中間件的控制
將響應主體設置為“Hello World”
計算持續時間
輸出日志行
計算響應時間
設置 X-Response-Time 頭字段
交給 Koa 處理響應
接下來,我們將介紹創建 Koa 中間件的最佳做法。
中間件最佳實踐本節介紹中間件創作最佳實踐,例如中間件接受參數,命名中間件進行調試等等。
中間件參數當創建公共中間件時,將中間件包裝在接受參數的函數中,遵循這個約定是有用的,允許用戶擴展功能。即使您的中間件 不 接受任何參數,這仍然是保持統一的好方法。
這里我們設計的 logger 中間件接受一個 format 自定義字符串,并返回中間件本身:
function logger(format) { format = format || ":method ":url""; return async function (ctx, next) { const str = format .replace(":method", ctx.method) .replace(":url", ctx.url); console.log(str); await next(); }; } app.use(logger()); app.use(logger(":method :url"));命名中間件
命名中間件是可選的,但是在調試中分配名稱很有用。
function logger(format) { return async function logger(ctx, next) { }; }將多個中間件與 koa-compose 相結合
有時您想要將多個中間件 “組合” 成一個單一的中間件,便于重用或導出。你可以使用 koa-compose
const compose = require("koa-compose"); async function random(ctx, next) { if ("/random" == ctx.path) { ctx.body = Math.floor(Math.random() * 10); } else { await next(); } }; async function backwards(ctx, next) { if ("/backwards" == ctx.path) { ctx.body = "sdrawkcab"; } else { await next(); } } async function pi(ctx, next) { if ("/pi" == ctx.path) { ctx.body = String(Math.PI); } else { await next(); } } const all = compose([random, backwards, pi]); app.use(all);響應中間件
中間件決定響應請求,并希望繞過下游中間件可以簡單地省略 next()。通常這將在路由中間件中,但這也可以任意執行。例如,以下內容將以 “two” 進行響應,但是所有三個都將被執行,從而使下游的 “three” 中間件有機會操縱響應。
app.use(async function (ctx, next) { console.log(">> one"); await next(); console.log("<< one"); }); app.use(async function (ctx, next) { console.log(">> two"); ctx.body = "two"; await next(); console.log("<< two"); }); app.use(async function (ctx, next) { console.log(">> three"); await next(); console.log("<< three"); });
以下配置在第二個中間件中省略了next(),并且仍然會以 “two” 進行響應,然而,第三個(以及任何其他下游中間件)將被忽略:
app.use(async function (ctx, next) { console.log(">> one"); await next(); console.log("<< one"); }); app.use(async function (ctx, next) { console.log(">> two"); ctx.body = "two"; console.log("<< two"); }); app.use(async function (ctx, next) { console.log(">> three"); await next(); console.log("<< three"); });
當最遠的下游中間件執行 next(); 時,它實際上是一個 noop 函數,允許中間件在堆棧中的任意位置正確組合。
異步操作Async 方法和 promise 來自 Koa 的底層,可以讓你編寫非阻塞序列代碼。例如,這個中間件從 ./docs 讀取文件名,然后在將給 body 指定合并結果之前并行讀取每個 markdown 文件的內容。
const fs = require("fs-promise"); app.use(async function (ctx, next) { const paths = await fs.readdir("docs"); const files = await Promise.all(paths.map(path => fs.readFile(`docs/${path}`, "utf8"))); ctx.type = "markdown"; ctx.body = files.join(""); });調試 Koa
Koa 以及許多構建庫,支持來自 debug 的 DEBUG 環境變量,它提供簡單的條件記錄。
例如,要查看所有 koa 特定的調試信息,只需通過 DEBUG=koa*,并且在啟動時,您將看到所使用的中間件的列表。
$ DEBUG=koa* node --harmony examples/simple koa:application use responseTime +0ms koa:application use logger +4ms koa:application use contentLength +0ms koa:application use notfound +0ms koa:application use response +0ms koa:application listen +0ms
由于 JavaScript 在運行時沒有定義函數名,你也可以將中間件的名稱設置為 ._name。當你無法控制中間件的名稱時,這很有用。例如:
const path = require("path"); const serve = require("koa-static"); const publicFiles = serve(path.join(__dirname, "public")); publicFiles._name = "static /public"; app.use(publicFiles);
現在,在調試時不只會看到 “serve”,你也會看到:
Now, instead of just seeing "serve" when debugging, you will see:
koa:application use static /public +0ms
如果這篇文章對您有幫助, 感謝 下方點贊 或 Star GitHub: koa-docs-Zh-CN 支持, 謝謝.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89495.html
摘要:一個遷移方式是逐個更新它們。刪除特定的日志記錄行為對于環境的顯式檢查從錯誤處理中刪除。直接或它不再使用并已廢棄。支持仍然支持分支,但應該不會得到功能性更新。除了此遷移指南外,文檔將針對最新版本。 從 Koa v1.x 遷移到 v2.x 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star. 新的中...
摘要:的對象提供了用于處理響應的方法,該響應委托給。應用對象是與的服務器和處理中間件注冊的接口,從發送到中間件,默認錯誤處理,以及上下文,請求和響應對象的配置。 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star. showImg(https://segmentfault.com/img/bVNQYf...
摘要:使用承諾和異步功能來擺脫回調地獄的應用程序,并簡化錯誤處理。它暴露了自己的和對象,而不是的和對象。因此,可被視為的模塊的抽象,其中是的應用程序框架。這使得中間件對于整個堆棧而言不僅僅是最終應用程序代碼,而且更易于書寫,并更不容易出錯。 Koa 與 Express 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新...
摘要:常見問題此系列文章的應用示例已發布于可以幫助改進或關注更新歡迎替代它更像是,但是很多的好東西被轉移到的中間件級別,以幫助形成更強大的基礎。這使得中間件對于整個堆棧而言不僅僅是最終應用程序代碼,而且更易于書寫,并更不容易出錯。 常見問題 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star. Koa...
摘要:但是,默認錯誤處理程序對于大多數用例來說都是足夠好的。錯誤偵聽器接收所有中間件鏈返回的錯誤,如果一個錯誤被捕獲并且不再拋出,它將不會被傳遞給錯誤偵聽器。 錯誤處理 此系列文章的應用示例已發布于 GitHub: koa-docs-Zh-CN. 可以 Fork 幫助改進或 Star 關注更新. 歡迎 Star. Try-Catch 使用 async 方法意味著你可以 try-catch n...
閱讀 1788·2023-04-26 01:44
閱讀 1217·2021-11-12 10:34
閱讀 1596·2021-09-09 09:33
閱讀 1734·2019-08-30 15:44
閱讀 2898·2019-08-30 13:49
閱讀 2194·2019-08-29 15:26
閱讀 947·2019-08-26 13:30
閱讀 1414·2019-08-23 18:15