# @esinx/async-context 中文文档

规范地址：https://npmcn.com/package/%40esinx/async-context/

版本：1\.0\.0-2
npm 元数据更新时间：2025-09-08T16:11:51.050Z
中文译文更新时间：2026-11-13T23:20:47.372Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40esinx/async-context
原文对照：https://npmcn.com/package/%40esinx/async-context/?lang=original
项目主页：https://github.com/esinx/async-context#readme
源码仓库：https://github.com/esinx/async-context

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：14.9 kB，6 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=16
- 运行依赖：0 个
- 首次发布：2025-06-28T05:10:02.438Z
- 最新版本发布：2025-09-08T16:11:50.831Z
- 近 30 天下载量：2928（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：3（近 12 个月 0 个）

## 中文简介

Async 语境管理 TypeScript 库

## 安装

```sh
npm install @esinx/async-context
```

也可以使用：`pnpm add @esinx/async-context`、`yarn add @esinx/async-context`、`bun add @esinx/async-context`

## README

# @ esinx/ aync- context

一个用于Async上下文管理的TypeScript库,使用由Node.js Async LocalStorage提供动力的React-like上下文API.

## 安装

```bash
npm install @esinx/async-context
# or
yarn add @esinx/async-context
# or
pnpm add @esinx/async-context
```

## 什么是同步背景?

Async 上下文允许您在整个Async调用链条中保存上下文信息,而不明确通过每个函数参数. 这对于:

-   **请求追查**: 在整个自动同步操作中维护请求ID
-   **用户背景**: 在整个请求处理过程中提供用户信息
-   **日志**: 在日志中自动包含背景信息
-   **数据库交易**: 维护全自动同步操作的交易环境
-   **地物标志**: 在整个应用程序中访问特性标记状态

## 问题

在传统的Async JavaScript/TypeScript代码中,通过多层的上下文可能繁琐:

```typescript
// Without async context - tedious parameter passing
async function handleRequest(userId: string, requestId: string) {
    const user = await fetchUser(userId, requestId)
    const data = await processData(user, requestId)
    await saveResult(data, userId, requestId)
}

async function fetchUser(userId: string, requestId: string) {
    console.log(`[${requestId}] Fetching user ${userId}`)
    // ... fetch logic
}

async function processData(user: User, requestId: string) {
    console.log(`[${requestId}] Processing data for ${user.id}`)
    // ... processing logic
}
```

## 解决办法

在同步语境下,您可以隐含地保持此信息:

```typescript
// With async context - clean and maintainable
const userContext = createContext<User | null>(null)
const requestContext = createContext<string>('')

async function handleRequest(userId: string, requestId: string) {
    await requestContext.run(requestId, async () => {
        const user = await fetchUser(userId)
        await userContext.run(user, async () => {
            const data = await processData()
            await saveResult(data)
        })
    })
}

async function fetchUser(userId: string) {
    const requestId = use(requestContext)
    console.log(`[${requestId}] Fetching user ${userId}`)
    // ... fetch logic
}

async function processData() {
    const user = use(userContext)
    const requestId = use(requestContext)
    console.log(`[${requestId}] Processing data for ${user.id}`)
    // ... processing logic
}
```

## 安装

```bash
npm install async-context
# or
yarn add async-context
# or
pnpm add async-context
```

## 快速启动

```typescript
import { createContext, use } from 'async-context'

// Create a context with a default value
const userContext = createContext<string>('anonymous')

// Run code with a specific context value
await userContext.run('john-doe', async () => {
    // All async operations in this scope have access to the context
    const currentUser = use(userContext) // 'john-doe'

    await someAsyncOperation()

    // Still available after async operations
    const stillCurrentUser = use(userContext) // 'john-doe'
})

// Outside the run scope, back to default
const defaultUser = use(userContext) // 'anonymous'
```

## API 参考

### `createContext<T>(initialValue: T): ContextHandle<T>`

创建一个带有初始/默认值的新上下文处理.

```typescript
const stringContext = createContext<string>('default')
const numberContext = createContext<number>(0)
const userContext = createContext<User | null>(null)
```

### `ContextHandle<T>`

该天体由 `createContext` 采用下列方法:

#### `handle.run<Result>(value: T, fn: () => Promise<Result>): Promise<Result>`

运行带有特定上下文值的async函数.

```typescript
const result = await handle.run('new-value', async () => {
    // Context is 'new-value' within this scope
    return await someAsyncOperation()
})
```

#### `handle.use(): T`

获得当前上下文值( 与独立值相同) `use` 函数).

```typescript
const currentValue = handle.use()
```

### `use<T>(handle: ContextHandle<T>): T`

从上下文控件获取当前值.

```typescript
const currentUser = use(userContext)
```

### `runWithContext<T>(handle: ContextHandle<T>, value: T)`

创建可重用功能,运行具有特定上下文值的操作.

```typescript
const runAsAdmin = runWithContext(userContext, adminUser)

const result = await runAsAdmin(async () => {
    // This runs with adminUser as the context
    return await performAdminOperation()
})
```

## 常见模式

### 请求追查

```typescript
import { createContext, use } from 'async-context'

const requestIdContext = createContext<string>('')

// Express middleware
app.use((req, res, next) => {
    const requestId = req.headers['x-request-id'] || generateId()
    requestIdContext.run(requestId, () => {
        next()
    })
})

// In any handler or service
async function processOrder() {
    const requestId = use(requestIdContext)
    logger.info(`Processing order`, { requestId })
    // ... processing logic
}
```

### 用户背景

```typescript
interface User {
    id: string
    role: string
    permissions: string[]
}

const userContext = createContext<User | null>(null)

// Authentication middleware
async function authenticate(token: string) {
    const user = await verifyToken(token)
    return userContext.run(user, async () => {
        // All subsequent operations have access to user context
        return await handleRequest()
    })
}

// In any service
async function createPost(data: PostData) {
    const currentUser = use(userContext)
    if (!currentUser) {
        throw new Error('Not authenticated')
    }

    if (!currentUser.permissions.includes('create:post')) {
        throw new Error('Insufficient permissions')
    }

    // ... create post logic
}
```

### 数据库交易

```typescript
const transactionContext = createContext<Transaction | null>(null)

async function withTransaction<T>(fn: () => Promise<T>): Promise<T> {
    const transaction = await db.beginTransaction()

    try {
        const result = await transactionContext.run(transaction, fn)
        await transaction.commit()
        return result
    } catch (error) {
        await transaction.rollback()
        throw error
    }
}

// Usage
await withTransaction(async () => {
    await createUser(userData)
    await createProfile(profileData)
    // Both operations use the same transaction automatically
})
```

### 嵌入上下文

```typescript
const tenantContext = createContext<string>('default')
const userContext = createContext<User | null>(null)

await tenantContext.run('tenant-123', async () => {
    await userContext.run(user, async () => {
        // Both contexts are available
        const tenant = use(tenantContext) // 'tenant-123'
        const currentUser = use(userContext) // user object

        await performOperation()
    })
})
```

## 高级使用

### 构成

```typescript
interface AppContext {
    user: User | null
    requestId: string
    tenant: string
}

const appContext = createContext<AppContext>({
    user: null,
    requestId: '',
    tenant: 'default',
})

// Helper function to create context
function createAppContext(user: User, requestId: string, tenant: string) {
    return { user, requestId, tenant }
}

await appContext.run(createAppContext(user, requestId, tenant), async () => {
    const { user, requestId, tenant } = use(appContext)
    // ... application logic
})
```

### 上下文提供者(类似反应模式)

```typescript
class ContextProvider {
    constructor(
        private userContext = createContext<User | null>(null),
        private requestContext = createContext<string>('')
    ) {}

    async provideContext<T>(
        user: User,
        requestId: string,
        fn: () => Promise<T>
    ): Promise<T> {
        return this.requestContext.run(requestId, async () => {
            return this.userContext.run(user, fn)
        })
    }

    getCurrentUser() {
        return use(this.userContext)
    }

    getCurrentRequestId() {
        return use(this.requestContext)
    }
}
```

## 最佳做法

1.  **使用有意义的默认值**: 选择适合您的应用程序的默认值
2.  **保持上下文不变**: 不要修改上下文对象; 改为创建新对象
3.  **避免经常变化的数据的背景**: 环境最适合相对稳定的信息
4.  **使用类型脚本**: 为上下文值利用类型安全
5.  **记录您的背景**: 明确每个上下文代表什么,何时可用
6.  **上下文测试**: 在测试中包含上下文情景

## 处理错误

当错误发生时, 上下文会自动清理 :

```typescript
try {
    await userContext.run(user, async () => {
        // Context is available here
        throw new Error('Something went wrong')
    })
} catch (error) {
    // Context is back to default/initial value
    const currentUser = use(userContext) // back to initial value
}
```

## 业绩考量

-   Async LocalStorage 大多数应用程序的间接费用都很少
-   上下文搜索非常快( O(1))
-   网格环境的额外费用极少
-   考虑对复杂状态使用上下文构成,而不是使用许多单个背景

## 所需资源

-   节点.js 16+(同步本地集成支持)
-   TypeScript 4.5+(用于最佳类型支持)

## 许可证

麻省理工学院

## 常见问题

### @esinx/async-context 是什么？

Async 语境管理 TypeScript 库

### 如何安装 @esinx/async-context？

在项目目录运行 npm install @esinx/async-context，或使用 pnpm add / yarn add / bun add。

### @esinx/async-context 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @esinx/async-context 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @esinx/async-context 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=16。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @esinx/async-context 可以商用吗？

@esinx/async-context 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @esinx/async-context 的下载量有多少？

根据 npm 官方下载统计，@esinx/async-context 在 2026/10/14 – 2026/11/12 这 30 天内被下载 2,928 次，日均约 98 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @esinx/async-context 还在维护吗？

最新版本 1\.0\.0-2 发布于 2025/09/09（1\.2 年前）；至今共发布 3 个版本，其中过去 12 个月发布了 0 个；首次发布于 2025/06/28。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

