after
after
允许你在响应(或预渲染)完成后调度要执行的工作。这对于不应阻塞响应的任务和其他副作用非常有用,例如日志记录和分析。
它可以用于服务器组件(包括 generateMetadata
)、服务器操作、路由处理程序和 中间件。
该函数接受一个回调,该回调将在响应(或预渲染)完成后执行
app/layout.tsx
import { after } from 'next/server'
// Custom logging function
import { log } from '@/app/utils'
export default function Layout({ children }: { children: React.ReactNode }) {
after(() => {
// Execute after the layout is rendered and sent to the user
log()
})
return <>{children}</>
}
须知:
after
不是一个 动态 API,调用它不会导致路由变为动态。如果在静态页面中使用,则回调将在构建时或页面重新验证时执行。
参考
参数
- 一个回调函数,它将在响应(或预渲染)完成后执行。
持续时间
after
将在平台的默认或配置的最大路由持续时间内运行。如果你的平台支持,你可以使用 maxDuration
路由段配置来配置超时限制。
须知
- 即使响应未成功完成,包括抛出错误或调用
notFound
或redirect
时,after
仍将执行。 - 你可以使用 React
cache
来去重在after
内部调用的函数。 after
可以嵌套在其他after
调用中,例如,你可以创建实用程序函数来包装after
调用以添加其他功能。
替代方案
after
的用例是在不阻塞主响应的情况下处理辅助任务。它类似于使用平台的 waitUntil()
或从 promise 中删除 await
,但有以下区别:
waitUntil()
:接受一个 promise 并将一个任务排队,以便在请求的生命周期内执行,而after
接受一个回调,该回调将在响应完成后执行。- 删除
await
:在响应期间开始执行,这会占用资源。在无服务器环境中也不可靠,因为函数在发送响应后立即停止计算,可能会中断任务。
我们建议使用 after
,因为它在设计时考虑了其他 Next.js API 和上下文。
示例
使用请求 API
你可以在 服务器操作 和 路由处理程序 中的 after
内部使用请求 API,例如 cookies
和 headers
。这对于记录变更后的活动很有用。例如:
app/api/route.ts
import { after } from 'next/server'
import { cookies, headers } from 'next/headers'
import { logUserAction } from '@/app/utils'
export async function POST(request: Request) {
// Perform mutation
// ...
// Log user activity for analytics
after(async () => {
const userAgent = (await headers().get('user-agent')) || 'unknown'
const sessionCookie =
(await cookies().get('session-id'))?.value || 'anonymous'
logUserAction({ sessionCookie, userAgent })
})
return new Response(JSON.stringify({ status: 'success' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
})
}
但是,你不能在 服务器组件 中的 after
内部使用这些请求 API。这是因为 Next.js 需要知道树的哪个部分访问了请求 API 以支持 部分预渲染,但 after
在 React 的渲染生命周期之后运行。
版本历史 | 描述 |
---|---|
v15.1.0 | after 变为稳定版。 |
v15.0.0-rc | 引入 unstable_after 。 |
这有帮助吗?