问题描述
在使用 Koa 进行 Web 开发时,很可能会遇到这样的问题:“async function in middleware didn't return a generator”。其中的 "async function" 指的是作为 Koa 中间件的异步函数,而 "generator" 则是 JavaScript 中的一种函数类型。
这个问题通常出现在我们使用 async/await
进行异步操作时,比如在读取文件、数据库查询、网络请求等操作时。假设我们有这样一个中间件:
async function myMiddleware(ctx, next) { // 异步操作 const result = await someAsyncFunction(); ctx.body = result; await next(); }
看起来似乎没什么问题,但在我们运行应用程序时,可能会遇到以下错误:
Error: async function in middleware didn't return a generator at dispatch (/path/to/koa/lib/application.js:208:13) at /path/to/koa/node_modules/koa-compose/index.js:42:12 at dispatch (/path/to/koa/node_modules/koa-compose/index.js:34:12) at /path/to/koa/app.js:40:5 ...
这个错误告诉我们中间件函数并没有返回一个符合要求的函数,导致 Koa 无法正确处理这个函数。
问题原因
问题在于 Koa 中间件的处理方式:Koa 会把中间件函数按顺序组成一个“洋葱模型”的调用链条,每个中间件函数都需要接收两个参数:ctx
和 next
。
而在这个调用链条中,每个中间件必须返回一个 Promise 对象,来确保下一个中间件能够正确地执行。这个 Promise 对象必须符合 ECMAScript 6 的 Generator 标准,因为 Koa 使用了 co 库来处理这个 Promise 对象。
但是,如果我们在中间件中使用了 async/await
,我们就会得到一个 Promise 对象,而不是一个 Generator,导致 Koa 无法正确处理这个 Promise 对象。
解决办法
我们需要将 async/await
函数转换成符合 Generator 标准的中间件函数。
手动编写转换器
我们可以手动编写一个转换器来将 async/await
函数转换成符合 Generator 标准的函数,例如:
-- -------------------- ---- ------- -------- --------------------- - ------ -------- ----- ----- - ------ ------------- ------- ------- -- - -- ---- ------------------------------- -------- ----- ----- - -- ---- ----- ------ - ----- -------------------- -------- - ------- ----- ------- ----
这里的 convertMiddleware
函数接受一个 async/await
函数作为参数,并返回一个新的中间件函数,这个新函数会将 async/await
函数转换成符合 Generator 标准的函数,并使用 co 库处理 Promise 对象。
使用第三方中间件
也可以使用第三方库 koa-async 来解决这个问题,总的来说就是把所有使用 async 的中间件都转成 generator 中间件。
-- -------------------- ---- ------- ----- -------- - -------------------- ---------------------- ----- ----- -- - -- ---- ----- ------ - ----- -------------------- -------- - ------- ----- ------- ---
总结
在使用 Koa 进行 Web 开发时,要避免出现 “async function in middleware didn't return a generator” 的问题,需要将 async/await
函数转换成符合 Generator 标准的函数,或使用 koa-async 库来处理这个问题。
随着 async/await 的普及,这个问题可能越来越少见,但我们作为前端开发者,不断学习和掌握新技术,才能更好地解决问题,提高开发效率和代码质量。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651e4da895b1f8cacd5f6fc9