Async 异步
all(所有)
等待多个承诺
all
函数类似于内置的 Promise.all 或 Promise.allSettled 函数。给定一个承诺列表(或对象),如果出现任何错误,则会收集所有错误并在 AggregateError 中抛出。
使用数组
将数组作为参数传递将会以相同顺序返回已解析的 Promise 值数组。
import { all } from 'radash'
const [user] = await all([
api.users.create(...),
s3.buckets.create(...),
slack.customerSuccessChannel.sendMessage(...)
])
使用对象
将对象作为参数传递,将返回具有相同键和已解析承诺值作为值的对象。
import { all } from 'radash'
const { user } = await all({
user: api.users.create(...),
bucket: s3.buckets.create(...),
message: slack.customerSuccessChannel.sendMessage(...)
})
defer(延迟)
运行一个带有延迟函数的异步函数
基本用法
_.defer
函数允许您运行异步函数,注册函数,这些函数应该推迟到异步函数完成后再执行。这在脚本中非常有用,如果在特定点之前或之后失败,将需要一些清理工作。这有点像一个 finally
块。
对 Swift 的 defer
表示致敬,他给予了灵感。
传递给 _.defer
的函数将使用单个 register
函数参数调用,该参数可用于注册您希望在函数完成时调用的工作。 如果您的函数抛出错误,然后注册的清理函数也抛出错误,默认情况下会被忽略。 注册函数支持可选的第二 options
参数,让您配置重新抛出策略,以便重新抛出清理函数中的错误。
import { defer } from "radash";
await defer(async (cleanup) => {
const buildDir = await createBuildDir();
cleanup(() => fs.unlink(buildDir));
await build();
});
await defer(async (register) => {
const org = await api.org.create();
register(async () => api.org.delete(org.id), { rethrow: true });
const user = await api.user.create();
register(async () => api.users.delete(user.id), { rethrow: true });
await executeTest(org, user);
});
guard(守卫)
如果出错,让函数返回 undefined
基本用法
这使您可以在异步函数出错时设置默认值。
const users = (await guard(fetchUsers)) ?? [];
您也可以选择仅保护特定的错误
const isInvalidUserError = (err: any) => err.code === "INVALID_ID";
const user = (await guard(fetchUser, isInvalidUserError)) ?? DEFAULT_USER;
map(映射)
使用异步函数映射数组
基本用法
处理返回 promise 的回调函数的映射。
import { map } from "radash";
const userIds = [1, 2, 3, 4];
const users = await map(userIds, async (userId) => {
return await api.users.find(userId);
});
parallel(并行)
并行运行多个异步函数
基本用法
类似于 _.map
,但专门用于并行运行异步回调函数。第一个参数是同时运行的函数数量限制。返回结果数组。
import { parallel } from "radash";
const userIds = [1, 2, 3, 4, 5, 6, 7, 8, 9];
// Will run the find user async function 3 at a time
// starting another request when one of the 3 is freed
const users = await parallel(3, userIds, async (userId) => {
return await api.users.find(userId);
});
Errors
当所有工作都完成后,将并行检查错误。如果发生任何错误,它们都将被抛出到一个具有一个 errors
属性的单个 AggregateError
中,该属性是所有被抛出的错误。
import { parallel, try as tryit } from "radash";
const userIds = [1, 2, 3];
const [err, users] = await tryit(parallel)(3, userIds, async (userId) => {
throw new Error(`No, I don\'t want to find user ${userId}`);
});
console.log(err); // => AggregateError
console.log(err.errors); // => [Error, Error, Error]
console.log(err.errors[1].message); // => No, I don't want to find user 2
reduce(减少)
使用异步函数减少数组
基本用法
处理返回 Promise 的回调函数的 reduce。
import { reduce } from "radash";
const userIds = [1, 2, 3, 4];
const users = await reduce(
userIds,
async (acc, userId) => {
const user = await api.users.find(userId);
return {
...acc,
[userId]: user,
};
},
{}
);
retry(重试)
运行异步函数,如果失败则重试
基本用法
_.retry
函数允许您运行一个异步函数,如果失败,会自动重试。给定要运行的异步函数、可选的最大重试次数( r
)和可选的重试之间延迟的毫秒数( d
),给定的异步函数将被调用,重试 r
次,并在重试之间等待 d
毫秒。
选项 times
默认为 3
。选项 delay
(默认为 null)可指定尝试之间的毫秒数。
backoff
选项类似于延迟,但使用函数来休眠——易于实现指数退避。
import { retry } from "radash";
await retry({}, api.users.list);
await retry({ times: 10 }, api.users.list);
await retry({ times: 2, delay: 1000 }, api.users.list);
// exponential backoff
await retry({ backoff: (i) => 10 ** i }, api.users.list);
sleep(睡眠)
异步等待时间流逝
基本用法
_.sleep
函数允许您延迟毫秒。
import { sleep } from "radash";
await sleep(2000); // => waits 2 seconds
tryit(尝试)
将函数转换为错误优先函数
基本用法
错误优先回调很酷。在尝试/捕获时使用可变变量来升级状态并不酷。
tryit
函数允许您包装一个函数,将其转换为错误优先函数。可用于异步和同步函数。
import { tryit } from "radash";
const [err, user] = await tryit(api.users.find)(userId);
柯里化
如果你喜欢,你可以给 tryit
加咖喱。
import { tryit } from "radash";
const findUser = tryit(api.users.find);
const [err, user] = await findUser(userId);