Koa 开发实践:解决 “async function in middleware didn't return a generator” 问题

阅读时长 4 分钟读完

问题描述

在使用 Koa 进行 Web 开发时,很可能会遇到这样的问题:“async function in middleware didn't return a generator”。其中的 "async function" 指的是作为 Koa 中间件的异步函数,而 "generator" 则是 JavaScript 中的一种函数类型。

这个问题通常出现在我们使用 async/await 进行异步操作时,比如在读取文件、数据库查询、网络请求等操作时。假设我们有这样一个中间件:

看起来似乎没什么问题,但在我们运行应用程序时,可能会遇到以下错误:

这个错误告诉我们中间件函数并没有返回一个符合要求的函数,导致 Koa 无法正确处理这个函数。

问题原因

问题在于 Koa 中间件的处理方式:Koa 会把中间件函数按顺序组成一个“洋葱模型”的调用链条,每个中间件函数都需要接收两个参数:ctxnext

而在这个调用链条中,每个中间件必须返回一个 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

纠错
反馈