在 Express 中,您可以在发送 HTTP 响应后执行代码,如下所示:
res.send()
await someAsyncFunction() // imagine this takes a very long time
在Next.js中,至少在本地环境中测试代码时,上面的工作方式与express相同。然而,一旦部署在 Vercel 上,上述代码似乎在发送 HTTP 响应后停止执行。我不知道这是否只是因为他们的无服务器功能就是这样设置的还是什么。所以我被迫像这样重新排列:
await someAsyncFunction() // imagine this takes a very long time
res.send()
这样排序的问题是,如果异步函数非常慢,则响应可能会在发回之前超时。在某些情况下,这很糟糕。假设我需要使用速率受限的 API 发送一堆电子邮件。这可能需要很长时间。我需要立即发送 HTTP 响应,然后再继续发送所有电子邮件的非常缓慢的过程。
我无法找到解释此行为的明确文档,但此 GitHub 讨论似乎确认,如果您在 Vercel 上部署,则在发送 HTTP 响应后无法执行代码:https://github.com/vercel/ next.js/discussions/14077
因此我被困在最后发送回复。
现在支持此功能,但仅在中间件中。
waitUntil() 方法接受一个 Promise 作为参数,并扩展了 中间件的生命周期,直到承诺解决。这很有用 用于在后台执行工作。
middleware.js
:
import { NextResponse } from 'next/server'
import type { NextFetchEvent, NextRequest } from 'next/server'
export function middleware(req: NextRequest, event: NextFetchEvent) {
event.waitUntil(
fetch('https://my-analytics-platform.com', {
method: 'POST',
body: JSON.stringify({ pathname: req.nextUrl.pathname }),
})
)
return NextResponse.next()
}