after
after
允许你安排在响应(或预渲染)完成后执行的工作。这对于不应阻止响应的任务和其他副作用很有用,例如日志记录和分析。
¥after
allows you to schedule work to be executed after a response (or prerender) is finished. This is useful for tasks and other side effects that should not block the response, such as logging and analytics.
它可以用于 服务器组件(包括 generateMetadata
)、服务器操作、路由处理程序 和 中间件。
¥It can be used in Server Components (including generateMetadata
), Server Actions, Route Handlers, and Middleware.
该函数接受在响应(或预渲染)完成后执行的回调:
¥The function accepts a callback that will be executed after the response (or prerender) is finished:
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,调用它不会导致路由变为动态。如果它在静态页面中使用,则回调将在构建时执行,或者在重新验证页面时执行。¥Good to know:
after
is not a Dynamic API and calling it does not cause a route to become dynamic. If it's used within a static page, the callback will execute at build time, or whenever a page is revalidated.
参考
¥Reference
参数
¥Parameters
响应(或预渲染)完成后将执行的回调函数。
¥A callback function which will be executed after the response (or prerender) is finished.
期间
¥Duration
after
将运行平台默认或配置的路由最大持续时间。如果你的平台支持,你可以使用 maxDuration
路由段配置来配置超时限制。
¥after
will run for the platform's default or configured max duration of your route. If your platform supports it, you can configure the timeout limit using the maxDuration
route segment config.
很高兴知道
¥Good to know
即使响应未成功完成,
after
也会执行。包括抛出错误或调用notFound
或redirect
时。¥
after
will be executed even if the response didn't complete successfully. Including when an error is thrown or whennotFound
orredirect
is called.你可以使用 React
cache
对after
内部调用的函数进行数据去重。¥You can use React
cache
to deduplicate functions called insideafter
.after
可以嵌套在其他after
调用中,例如,你可以创建封装after
调用的实用程序函数来添加其他功能。¥
after
can be nested inside otherafter
calls, for example, you can create utility functions that wrapafter
calls to add additional functionality.
示例
¥Examples
使用请求 API
¥With request APIs
你可以在 服务器操作 和 路由处理程序 中的 after
中使用请求 API(如 cookies
和 headers
)。这对于在突变后记录活动很有用。例如:
¥You can use request APIs such as cookies
and headers
inside after
in Server Actions and Route Handlers. This is useful for logging activity after a mutation. For example:
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 的渲染生命周期之后运行。
¥However, you cannot use these request APIs inside after
in Server Components. This is because Next.js needs to know which part of the tree access the request APIs to support Partial Prerendering, but after
runs after React's rendering lifecycle.
平台支持
¥Platform Support
部署选项 | 支持 |
---|---|
Node.js 服务器 | 是 |
Docker 容器 | 是 |
静态导出 | 否 |
适配器 | 平台相关 |
了解如何在自托管 Next.js 时进行 配置 after
。
¥Learn how to configure after
when self-hosting Next.js.
Reference: supporting `after` for serverless platforms
Using `after` in a serverless context requires waiting for asynchronous tasks to finish after the response has been sent. In Next.js and Vercel, this is achieved using a primitive called `waitUntil(promise)`, which extends the lifetime of a serverless invocation until all promises passed to [`waitUntil`](https://vercel.com/docs/functions/functions-api-reference#waituntil) have settled.如果你希望用户能够运行 after
,则必须提供以类似方式运行的 waitUntil
实现。
¥If you want your users to be able to run after
, you will have to provide your implementation of waitUntil
that behaves in an analogous way.
调用 after
时,Next.js 将像这样访问 waitUntil
:
¥When after
is called, Next.js will access waitUntil
like this:
这意味着 globalThis[Symbol.for('@next/request-context')]
应该包含这样的对象:
¥Which means that globalThis[Symbol.for('@next/request-context')]
is expected to contain an object like this:
type NextRequestContext = {
get(): NextRequestContextValue | undefined
}
type NextRequestContextValue = {
waitUntil?: (promise: Promise<any>) => void
}
以下是实现的示例。
¥Here is an example of the implementation.
import { AsyncLocalStorage } from 'node:async_hooks'
const RequestContextStorage = new AsyncLocalStorage<NextRequestContextValue>()
// Define and inject the accessor that next.js will use
const RequestContext: NextRequestContext = {
get() {
return RequestContextStorage.getStore()
},
}
globalThis[Symbol.for('@next/request-context')] = RequestContext
const handler = (req, res) => {
const contextValue = { waitUntil: YOUR_WAITUNTIL }
// Provide the value
return RequestContextStorage.run(contextValue, () => nextJsHandler(req, res))
}
版本历史
¥Version History
版本历史 | 描述 |
---|---|
v15.1.0 | after 已稳定。 |
v15.0.0-rc | unstable_after 已引入。 |