摘要:当中间件运行时,它必须手动调用来运行下游中间件。例如,这个中间件从读取文件名,然后在将给指定合并结果之前并行读取每个文件的内容。当你无法控制中间件的名称时,这很有用。
指南
此系列文章的应用示例已发布于 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 支持, 谢谢.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/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...
阅读 1723·2023-04-26 01:44
阅读 1186·2021-11-12 10:34
阅读 1502·2021-09-09 09:33
阅读 1710·2019-08-30 15:44
阅读 2851·2019-08-30 13:49
阅读 2165·2019-08-29 15:26
阅读 918·2019-08-26 13:30
阅读 1389·2019-08-23 18:15