# @api3/promise-utils 中文文档

规范地址：https://npmcn.com/package/%40api3/promise-utils/

版本：0\.4\.0
npm 元数据更新时间：2026-04-07T10:33:25.139Z
中文译文更新时间：2026-11-06T10:46:26.312Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40api3/promise-utils
原文对照：https://npmcn.com/package/%40api3/promise-utils/?lang=original
源码仓库：https://github.com/api3dao/promise-utils

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

- 包体积（解压后）：84 kB，20 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：未声明
- 运行依赖：0 个
- 首次发布：2022-03-15T11:08:56.754Z
- 最新版本发布：2023-03-21T12:28:07.167Z
- 近 30 天下载量：3432（2026-10-06 至 2026-11-04，npm 官方下载统计）
- 已发布版本数：4（近 12 个月 0 个）

## 中文简介

> 一个简单的零依赖性功能和类型安全错误处理软件包

## 安装

```sh
npm install @api3/promise-utils
```

也可以使用：`pnpm add @api3/promise-utils`、`yarn add @api3/promise-utils`、`bun add @api3/promise-utils`

## README

# 承诺工具 [![ContinuousBuild](https://github.com/api3dao/promise-utils/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/api3dao/promise-utils/actions/workflows/main.yml)

> 一个简单的零依赖性功能和类型安全错误处理软件包

## 安装

要安装此软件包, 请运行 :

`yarn add @api3/promise-utils`

或者如果您使用 npm :

`npm install @api3/promise-utils --save`

## 使用量

API规模小,重点突出提供 [更简洁的错误处理](https://npmcn.com/package/%40api3/promise-utils/#readme-motivation). 主要职能 软件包是 `go` 财务报告和审定财务报表 `goSync` 函数。 他们接受一个执行的功能,另外 `go` 接受可选选项 `GoAsyncOptions` 对象作为第二个参数。 如果函数执行时没有出错,则成功响应 数据返回,否则返回错误反应.

```ts
// Imagine an async function for fetching API data
const goFetchData = await go(() => fetchData('users'));
// The "goFetchData" value is either: {success: true, data: ...} or {success: false, error: ...}
if (goFetchData.success) {
  const data = goFetchData.data
  ...
}
```

或:

```ts
// Imagine an async function for fetching API data
// If the fetch data is a non class function returning a promise, you can drop the arrow function
const goFetchData = await go(() => fetchData('users'));
// The "goFetchData" value is either: {success: true, data: ...} or {success: false, error: ...}
if (!goFetchData.success) {
  const error = goFetchData.error
  ...
}
```

并带有 `GoAsyncOptions`数字 :

```ts
// The `fetchData` function will be retried a maximum of 2 times on error, with each attempt having
// a timeout of 5 seconds and a total timeout 10 seconds (shared among all attempts and delays).
const goFetchData = await go(() => fetchData('users'), { retries: 2, attemptTimeoutMs: 5_000, totalTimeoutMs: 10_000 });
...
```

,用于同步函数:

```ts
const someData = ...
// Imagine a synchronous function for parsing data
const goParseData = goSync(() => parseData(someData));
// The goParseData value is either: {success: true, data: ...} or {success: false, error: ...}
if (goParseData.success) {
  const data = goParseData.data
  ...
}
```

从承诺的 utils 函数返回值与 TypeScript 推论非常一致 。 当你检查 `success` 属性, TypeScript 将推断正确的响应类型.

## API 密码

全数 `promise-utils` API由以下功能组成:

-   `go(asyncFn, options)` - 执行 `asyncFn` 返回类型响应 `GoResult`
-   `goSync(fn)` - 执行 `fn` 返回类型响应 `GoResult`
-   `assertGoSuccess(goRes)` - 证明: `goRes` 是一种成功的对策(`GoResultSuccess` 类型)和投掷 否则.
-   `assertGoError(goRes)` - 证明: `goRes` 是一个错误的响应( n)`GoResultError` 类型),并另投.
-   `success(value)` - 创建成功结果值,特别是 `{success: true, data: value}`
-   `fail(error)` - 创建出错结果,特别是 `{success: false, error: error}`

和下列打字机类型:

-   ```ts
    type GoResult<T> = { data: T; success: true };
    ```
    
-   ```ts
    type GoResultSuccess<E extends Error = Error> = { error: E; success: false };
    ```
    
-   ```ts
    type GoResultError<T, E extends Error = Error> = GoResultSuccess<T> | GoResultError<E>;
    ```
    
-   ```ts
    interface GoAsyncOptions<E extends Error = Error> {
      retries?: number; // Number of retries to attempt if the go callback is unsuccessful.
      attemptTimeoutMs?: number | number[]; // The timeout for each attempt. Can provide an array for different timeouts for each attempt. If the array is shorter than the number of retries, the last value is used for all remaining attempts, if the length of the array is longer than the number of retries, the extra values are ignored.
      totalTimeoutMs?: number; // The maximum timeout for all attempts and delays. No more retries are performed after this timeout.
      delay?: StaticDelayOptions | RandomDelayOptions; // Type of the delay before each attempt. There is no delay before the first request.
      onAttemptError?: (goRes: GoResultError<E>) => void; // Callback invoked after each failed attempt is completed. This callback does not fire for the last attempt or when a "totalTimeoutMs" is exceeded (these should be handled explicitly with the result of "go" call).
    }
    ```
    
-   ```ts
    interface StaticDelayOptions {
      type: 'static';
      delayMs: number;
    }
    ```
    
-   ```ts
    interface RandomDelayOptions {
      type: 'random';
      minDelayMs: number;
      maxDelayMs: number;
    }
    ```
    

小心点 `attemptTimeoutMs` 价值 `0` 表示暂停0毫秒. 如果您想要无限超时, 请省略密钥或 准备吧 `undefined`。 。 。 .

最后一个导出值为 a `GoWrappedError` 类,该类将一个在回调时发生的错误包裹起来。 差别 介于 `GoWrappedError` 经常 `Error` 类是您可以访问 `GoWrappedError.reason` 获取原始 被函数所抛出的价值.

看看这个 [执行](https://github.com/api3dao/promise-utils/blob/main/src/index.ts) 财务报告和审定财务报表 [测试](https://github.com/api3dao/promise-utils/blob/main/src/index.test.ts) 详细的例子和使用.

## 动机

### 试捕模式的可操作性和互操作性

```ts
// Verbose try catch
try {
  const data = await someAsyncCall();
  ...
} catch (e) {
  // The "e" is "unknown" because any value can be thrown in Javascript so casting is needed
  return logError((e as MyError).reason);
}

// Compare it to simpler version using go
const goRes = await go<MyData, MyError>(someAsyncCall);
if (!goRes.success) return logError(goRes.error.reason);
// At this point TypeScript infers that the error was handled and "goRes" must be a success response
const data = goRes.data;
...
```

另外,想想在单个函数调用中要处理多个"可以失败"操作时会发生什么. 你们可以 要么:

1.  让他们在同样的尝试捕捉区块 - 但是,很难区分 是什么出了错误. 而且这通常会导致一个尝试区块内有很多代码,而捕获条款的行为更像是"捕获任何东西".
2.  使用巢来尝试捕获块 - 但这伤害了可读性,迫使你进入 [回调地狱模式](http://callbackhell.com/)。 。 。 .

### 不断扔出一个 `Error` 实例

JavaScript 支持扔出任何表达式,而不仅仅是 `Error` 实例。 这也是TypeScript推断 错误为 `unknown` 或者说 `any` (见: [使用未知的 InCatch 变量](https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables)) (中文(简体) ).

错误响应来自 `go` 财务报告和审定财务报表 `goSync` 总是返回一个实例 `Error` 课。 当然了,抛出风俗 出错(来自 `Error`) 得到支持.

### 故意有限特性集

设计时的去除功能只提供非常基本的超时和重试能力,因为这些能力往往是应用特定的和 可能很快导致布局膨胀. 如果您在寻找更复杂的特性,请考虑使用其中之一 备选办法,例如:. [https://github.com/lifeomic/attoption (中文(简体) )](https://github.com/lifeomic/attempt)

## 限制

由于 Javascript 如何使用类函数有限制 [这个](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) 工作时.

```ts
class MyClass {
  constructor() {}
  get() {
    return this._get();
  }
  _get() {
    return '123';
  }
}

const myClass = new MyClass();
const resWorks = goSync(() => myClass.get()); // This works
// However, seeing the line above it may be tempting to rewrite it to
const resFails = goSync(myClass.get); // This doesn't work
```

问题是 `this` 关键词由函数的调用方式决定,在第二个例子中 `this` 内部 `get` 函数是 `undefined` 这使得 `this._get()` 投出一个错误.

## 开发者文档

### 释放

按照这些步骤发布新版本:

1.  `yarn && yarn build`
2.  `yarn version` 并选择要发布的版本
3.  `yarn publish --access public`
4.  `git push --follow-tags`

## 常见问题

### @api3/promise-utils 是什么？

一个简单的零依赖性功能和类型安全错误处理软件包

### 如何安装 @api3/promise-utils？

在项目目录运行 npm install @api3/promise-utils，或使用 pnpm add / yarn add / bun add。

### @api3/promise-utils 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/api3\_\_promise-utils 是否存在。

### @api3/promise-utils 支持 ESM 还是 CommonJS？

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

### @api3/promise-utils 可以商用吗？

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

### @api3/promise-utils 的下载量有多少？

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

### @api3/promise-utils 还在维护吗？

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

