基于Express服务器的Remix应用中异步上下文追踪实现方案
解决Remix + Express中AsyncLocalStorage上下文跨中间件/loader共享问题
核心问题是你原来的实现没有等待异步处理完成就退出了AsyncLocalStorage的上下文,导致Remix的loader/action执行时上下文已经丢失。以下是修正后的完整实现:
1. 修正上下文工具类(ctx.ts)
import { AsyncLocalStorage } from "node:async_hooks"; import { randomUUID } from "node:crypto"; export const asyncLocalStorage = new AsyncLocalStorage<string>(); // 修正:确保await传入的异步函数,避免上下文提前退出 export const createContext = async (fn: () => Promise<void> | void) => { // 生成请求唯一的Trace ID const traceId = randomUUID(); await asyncLocalStorage.run(traceId, async () => { await fn(); }); }; export const getTraceId = () => { return asyncLocalStorage.getStore(); };
2. 调整Express服务器配置(server.ts)
import { createRequestHandler } from "@remix-run/express"; import express from "express"; import { createContext, getTraceId } from "./ctx"; const initialBuild = await import("./build/index.js"); const app = express(); const remixHandler = createRequestHandler({ build: initialBuild, mode: initialBuild.mode, }); // 关键:用async中间件包裹createContext,并await它 app.use(async (req, res, next) => { await createContext(next); }); // 测试中间件:可以正常获取Trace ID app.use((req, res, next) => { console.log("中间件中的Trace ID:", getTraceId()); next(); }); // Remix请求处理:现在loader/action也能拿到上下文 app.all("*", remixHandler); app.listen(3000, () => console.log("Server running on http://localhost:3000"));
3. 在Remix Loader/Action中验证
import { LoaderFunctionArgs, ActionFunctionArgs } from "@remix-run/node"; import { getTraceId } from "~/ctx"; export const loader = async ({ request }: LoaderFunctionArgs) => { console.log("Loader中的Trace ID:", getTraceId()); return new Response("OK"); }; export const action = async ({ request }: ActionFunctionArgs) => { console.log("Action中的Trace ID:", getTraceId()); return new Response("OK"); };
原理说明
- 原来的实现中,
createContext没有等待next()对应的异步处理完成,导致AsyncLocalStorage的上下文在Remix处理请求前就已销毁。 - 修正后,通过
await fn()确保整个请求的异步处理流程(包括后续中间件、Remix的loader/action执行)都处于AsyncLocalStorage的上下文范围内。 - 全程共享同一个Trace ID,无需通过
getLoadContext传递,实现请求级别的上下文统一。
内容的提问来源于stack exchange,提问作者Peadar Doyle
相关产品推荐
相关产品推荐

