承诺工具 
一个简单的零依赖性功能和类型安全错误处理软件包
安装
要安装此软件包, 请运行 :
yarn add @api3/promise-utils
或者如果您使用 npm :
npm install @api3/promise-utils --save
使用量
API规模小,重点突出提供 更简洁的错误处理. 主要职能
软件包是 go 财务报告和审定财务报表 goSync 函数。 他们接受一个执行的功能,另外 go 接受可选选项
GoAsyncOptions 对象作为第二个参数。 如果函数执行时没有出错,则成功响应
数据返回,否则返回错误反应.
// 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
...
}
或:
// 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数字 :
// 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 });
...
,用于同步函数:
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返回类型响应GoResultgoSync(fn)- 执行fn返回类型响应GoResultassertGoSuccess(goRes)- 证明:goRes是一种成功的对策(GoResultSuccess类型)和投掷 否则.assertGoError(goRes)- 证明:goRes是一个错误的响应( n)GoResultError类型),并另投.success(value)- 创建成功结果值,特别是{success: true, data: value}fail(error)- 创建出错结果,特别是{success: false, error: error}
和下列打字机类型:
-
type GoResult<T> = { data: T; success: true }; -
type GoResultSuccess<E extends Error = Error> = { error: E; success: false }; -
type GoResultError<T, E extends Error = Error> = GoResultSuccess<T> | GoResultError<E>; -
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). } -
interface StaticDelayOptions { type: 'static'; delayMs: number; } -
interface RandomDelayOptions { type: 'random'; minDelayMs: number; maxDelayMs: number; }
小心点 attemptTimeoutMs 价值 0 表示暂停0毫秒. 如果您想要无限超时, 请省略密钥或
准备吧 undefined。 。 。 .
最后一个导出值为 a GoWrappedError 类,该类将一个在回调时发生的错误包裹起来。 差别
介于 GoWrappedError 经常 Error 类是您可以访问 GoWrappedError.reason 获取原始
被函数所抛出的价值.
看看这个 执行 财务报告和审定财务报表 测试 详细的例子和使用.
动机
试捕模式的可操作性和互操作性
// 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;
...
另外,想想在单个函数调用中要处理多个"可以失败"操作时会发生什么. 你们可以 要么:
- 让他们在同样的尝试捕捉区块 - 但是,很难区分 是什么出了错误. 而且这通常会导致一个尝试区块内有很多代码,而捕获条款的行为更像是"捕获任何东西".
- 使用巢来尝试捕获块 - 但这伤害了可读性,迫使你进入 回调地狱模式。 。 。 .
不断扔出一个 Error 实例
JavaScript 支持扔出任何表达式,而不仅仅是 Error 实例。 这也是TypeScript推断
错误为 unknown 或者说 any (见:
使用未知的 InCatch 变量) (中文(简体) ).
错误响应来自 go 财务报告和审定财务报表 goSync 总是返回一个实例 Error 课。 当然了,抛出风俗
出错(来自 Error) 得到支持.
故意有限特性集
设计时的去除功能只提供非常基本的超时和重试能力,因为这些能力往往是应用特定的和 可能很快导致布局膨胀. 如果您在寻找更复杂的特性,请考虑使用其中之一 备选办法,例如:. https://github.com/lifeomic/attoption (中文(简体) )
限制
由于 Javascript 如何使用类函数有限制 这个 工作时.
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() 投出一个错误.
开发者文档
释放
按照这些步骤发布新版本:
yarn && yarn buildyarn version并选择要发布的版本yarn publish --access publicgit push --follow-tags