# @farmersdog/cls-hooked 中文文档

规范地址：https://npmcn.com/package/%40farmersdog/cls-hooked/

版本：5\.0\.0
npm 元数据更新时间：2026-09-16T17:13:40.592Z
中文译文更新时间：2026-11-14T10:23:53.829Z
软件包许可：BSD-2-Clause

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

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

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

- 包体积（解压后）：56.8 kB，10 个文件
- 模块格式：CommonJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.0
- 运行依赖：0 个
- 首次发布：2022-03-29T20:05:51.188Z
- 最新版本发布：2026-09-16T17:13:40.436Z
- 近 30 天下载量：23231（2026-10-15 至 2026-11-13，npm 官方下载统计）
- 已发布版本数：7（近 12 个月 5 个）

## 中文简介

Cls-hoked 软件包的叉子,由"农夫的狗"工程公司维护

## 安装

```sh
npm install @farmersdog/cls-hooked
```

也可以使用：`pnpm add @farmersdog/cls-hooked`、`yarn add @farmersdog/cls-hooked`、`bun add @farmersdog/cls-hooked`

## README

# 继续当地储存(挂上)

这是一个维护的叉子 [杰夫 - 勒维斯/克勒斯-霍克德](https://github.com/Jeff-Lewis/cls-hooked) 软件包。 这个 公用 API 将保持不变, 这样可以继续被任意使用 软件包,取决于续作-本地存储执行.

## 在新项目中不要使用此选项

新代码应该使用节点的内置 [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html) 直接 - 它稳定,保存良好,涵盖了这个一揽子计划所做的一切。 这个 使用此软件包的唯一理由是一个已经存在的 遗留/褐地代码库 依赖于 CLS API( 直接, 或通过Sequelize 等依赖) 6号 `useCLS`),无法消除这种依赖性,原因有不同.

## v5: Async LocalStorage 内部设备

至五一起 内部是建在节点的马厩上 [`AsyncLocalStorage`](https://nodejs.org/api/async_context.html) 改为 不稳定的,没有保持 `async_hooks` API (英语). 公用API是一个滴入 替换 v4, 通过对 v4 的差分测试加以核实 执行(包括端到端的快件和序列v6) `useCLS` 流动)。 需要22号节点.

有一些故意的行为改变,所有这些都地址为v4上下文泄露. 见 [变化](https://npmcn.com/package/%40farmersdog/cls-hooked/CHANGELOG.md#v500) 详细情况.

v5 还有 **零运行时间依赖关系**: 废弃 `emitter-listener` 软件包后面 `bindEmitter` 被一个测试单元取代 当听众被添加而不是被补丁的时候,他们将受约束 `emit` (见《大会正式记录,第五十八届会议,补编第6号》) [变化](https://npmcn.com/package/%40farmersdog/cls-hooked/CHANGELOG.md#v500) 对于少数可见的差异.

v5 舰只本身的TypeScript申报,形状为倒置替代 页:1 `@types/cls-hooked` ——当 升级;不需要更改代码.

## 使用量

* * *

继续本地存储工作, 如线程本地存储在线程中 编程,但基于节点风格回调的链条而不是线程. 调用函数的标准节点惯例与调用函数非常相近 在功能编程中称为\["contination-passing style" \[cps\]的东西, 名称来自此模块允许您设置并获取值的方式 范围可追溯到这些功能链的召唤寿命.

假设您正在写一个模块来获取用户并添加到会话中 在调用用户传递的函数继续执行之前:

```javascript
// setup.js

var createNamespace = require("cls-hooked").createNamespace;
var session = createNamespace("my session");

var db = require("./lib/db.js");

function start(options, next) {
  db.fetchUserById(options.id, function (error, user) {
    if (error) return next(error);

    session.set("user", user);

    next();
  });
}
```

稍后在将用户的数据转换成 HTML 页面的过程中,您会拨打 另一个想要获取的函数( 可能在另一个模块中完全定义) 您早先设定的值 :

```javascript
// send_response.js

var getNamespace = require("cls-hooked").getNamespace;
var session = getNamespace("my session");

var render = require("./lib/render.js");

function finish(response) {
  var user = session.get("user");
  render({ user: user }).pipe(response);
}
```

当设置值为续行- 本地存储时, 这些值可以访问 直到从原始函数调用的所有函数 –同步或 同步执行 。 包括向 `process.nextTick` 和 \[定时函数\] (\[setImmed\]\[\], \[设置时通 \[和\[设置时通 \[\]),以及转至 调用本地函数的同步函数(例如导出自 页:1 `fs`, (中文(简体) ), `dns`, (中文(简体) ), `zlib` 财务报告和审定财务报表 `crypto` 页:1.

一个简单的拇指规则是任何地方 你可能设置一个属性 `request` 或者说 `response` 在 HTTP 处理器中的对象, 您可以( 并且应该) 现在 使用续作 - 本地存储。 此 API 旨在允许您扩展 跨函数调用序列的变量范围,但有值 具体针对每个通话顺序.

值被组合成命名空间,创建于 `createNamespace()`组合 函数的调用通过调用在所传递的函数内进行组合 改为 `.run()` 在命名空间对象上。 呼吁 `.run()` 可以筑巢,每个 此创建的嵌入上下文有自己的一组值的复制件 父环境。 当一个函数进行多个同步调用时, 此 允许每个孩子的通话得到、设置和传递自己的上下文,而无需 覆写父母.

一个简单的,注解性的例子 如何这种筑巢行为:

```javascript
var createNamespace = require("cls-hooked").createNamespace;

var writer = createNamespace("writer");
writer.run(function () {
  writer.set("value", 0);

  requestHandler();
});

function requestHandler() {
  writer.run(function (outer) {
    // writer.get('value') returns 0
    // outer.value is 0
    writer.set("value", 1);
    // writer.get('value') returns 1
    // outer.value is 1
    process.nextTick(function () {
      // writer.get('value') returns 1
      // outer.value is 1
      writer.run(function (inner) {
        // writer.get('value') returns 1
        // outer.value is 1
        // inner.value is 1
        writer.set("value", 2);
        // writer.get('value') returns 2
        // outer.value is 1
        // inner.value is 2
      });
    });
  });

  setTimeout(function () {
    // runs with the default context, because nested contexts have ended
    console.log(writer.get("value")); // prints 0
  }, 1000);
}
```

## cls.create Namespace( 名称)

-   返回 : {Namespace}

每一个想要使用续作的应用程序 - 本地值应该创建自己的 名称空间。 从(或更重要的是,从写到)命名空间读取 不要属于你是一个傻瓜.

## cls.get Namespace( 名称)

-   返回 : {Namespace}

查找已有的命名空间 .

## cls.dstroy Namespace( 名称)

处理已存在的命名空间 。 警告:确保处理任何参考文献 用于您旧代码中已销毁的命名空间, 因为与之相关的上下文 不再被宣传.

## cls.reset () (中文(简体) )

完全重置所有续作 - 本地存储名空间 。 警告:而这个 如果有,将停止在任何现有的命名空间中传播值 引用代码中的命名空间, 相关存储将 尽管相关状态不再更新,但仍然可以达到. 确保你清理任何引用 被破坏的命名空间自己.

## cls.get Namespaces () (中文(简体) )

-   返回: {Namespace} 对象的字典

返回按名称键的所有命名空间的注册( E)`null` 标记 a 已销毁的命名空间 。 在v5之前,这个登记册一直存在 `process.namespaces`, (中文(简体) ), 它在测试跑道上漏出不同模块的命名空间 横跨共存的图书库副本;现在是模块-本地版.

## 类: 命名空间

应用程序特定命名空间组值 他们的电话来源于回话 `namespace.run()` 或者说 `namespace.bind()`。 。 。 .

### 名称空间. 活动

-   返回:名称空间上当前活跃的上下文

### namespace. set( 键, 值)

-   返回 : `value`

在当前继续上下文上设定一个值 。 必须在活动内设置 继续链开始于 `namespace.run()` 或者说 `namespace.bind()`。 。 。 .

### namespace.get( 键)

-   返回:请求的值,或 `undefined`

查找当前继续上下文的值 。 递归搜索从 相关值的最内到最外接续上下文 和给定的钥匙 必须设置在以 `namespace.run()` 或者说 `namespace.bind()`。 。 。 .

### namespace.run( 回调)

-   返回:与召回相关的上下文

创建一个可以设定或读取数值的新上下文。 运行全部函数 直接或间接通过同步函数 )从在以下范围内提供的回调中调出: 那个名字空间。 新上下文被传递为回调的论据 当名为相.

### namespace. run And Return( 回调)

-   返回: 回调的返回值

创建一个可以设定或读取数值的新上下文。 运行全部函数 直接或间接通过同步函数 )从在以下范围内提供的回调中调出: 那个名字空间。 新上下文被传递为回调的论据 当名为相.

与 `namespace.run()` 但返回回调的返回值 而不是上下文.

### namespace.bind(召回,\[文 )

-   返回:在上下文关闭时包裹的回调

将函数绑入指定的命名空间 。 类似工作 `Function.bind()` 或者说 `domain.bind()`如果省略上下文,则默认为 名称空间中当前活跃的上下文,或者创建新上下文,如果没有 当前定义.

### 名称空间. bindEmitter( emiters)

将事件编辑器绑入命名空间 。 类似操作 `domain.add`,带有 较少的通用名称和与域、命名空间不同的附加提醒 永不隐含束缚 事件Emitters 自己 当他们创建在内部 的上下文.

你最可能想要使用这个的时间是 当你使用快递或 连接并想要确保您的中间软件执行与 CLS 播放良好, 或者 正在和 HTTP 听众一起做其它工作 :

```javascript
http.createServer(function (req, res) {
  writer.bindEmitter(req);
  writer.bindEmitter(res);

  // do other stuff, some of which is asynchronous
});
```

### 命名空间. 创建 Context ()

-   返回:从当前活动上下文复制的上下文

用这个 `namespace.bind()`如果你想在引用时有新的上下文, 相对于约束时间:

```javascript
function doSomething(p) {
  console.log("%s = %s", p, ns.get(p));
}

function bindLater(callback) {
  return writer.bind(callback, writer.createContext());
}

setInterval(function () {
  var bound = bindLater(doSomething);
  bound("test");
}, 100);
```

## 上下文

上下文是使用附着上下文作为原型创建的平面对象.

## 版权和许可证

见 [自由主义](https://github.com/jeff-lewis/cls-hooked/blob/master/LICENSE)

## 常见问题

### @farmersdog/cls-hooked 是什么？

Cls-hoked 软件包的叉子,由"农夫的狗"工程公司维护

### 如何安装 @farmersdog/cls-hooked？

在项目目录运行 npm install @farmersdog/cls-hooked，或使用 pnpm add / yarn add / bun add。

### @farmersdog/cls-hooked 支持 TypeScript 吗？

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

### @farmersdog/cls-hooked 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @farmersdog/cls-hooked 需要什么版本的 Node\.js？

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

### @farmersdog/cls-hooked 可以商用吗？

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

### @farmersdog/cls-hooked 的下载量有多少？

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

### @farmersdog/cls-hooked 还在维护吗？

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

