Skip to content

Async 异步

all(所有)

等待多个承诺

all 函数类似于内置的 Promise.all 或 Promise.allSettled 函数。给定一个承诺列表(或对象),如果出现任何错误,则会收集所有错误并在 AggregateError 中抛出。

使用数组

将数组作为参数传递将会以相同顺序返回已解析的 Promise 值数组。

ts
import { all } from 'radash'

const [user] = await all([
  api.users.create(...),
  s3.buckets.create(...),
  slack.customerSuccessChannel.sendMessage(...)
])

使用对象

将对象作为参数传递,将返回具有相同键和已解析承诺值作为值的对象。

ts
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 参数,让您配置重新抛出策略,以便重新抛出清理函数中的错误。

ts
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

基本用法

这使您可以在异步函数出错时设置默认值。

ts
const users = (await guard(fetchUsers)) ?? [];

您也可以选择仅保护特定的错误

ts
const isInvalidUserError = (err: any) => err.code === "INVALID_ID";
const user = (await guard(fetchUser, isInvalidUserError)) ?? DEFAULT_USER;

map(映射)

使用异步函数映射数组

基本用法

处理返回 promise 的回调函数的映射。

ts
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 ,但专门用于并行运行异步回调函数。第一个参数是同时运行的函数数量限制。返回结果数组。

ts
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 中,该属性是所有被抛出的错误。

ts
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。

ts
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 选项类似于延迟,但使用函数来休眠——易于实现指数退避。

ts
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 函数允许您延迟毫秒。

ts
import { sleep } from "radash";

await sleep(2000); // => waits 2 seconds

tryit(尝试)

将函数转换为错误优先函数

基本用法

错误优先回调很酷。在尝试/捕获时使用可变变量来升级状态并不酷。

tryit 函数允许您包装一个函数,将其转换为错误优先函数。可用于异步和同步函数。

ts
import { tryit } from "radash";

const [err, user] = await tryit(api.users.find)(userId);

柯里化

如果你喜欢,你可以给 tryit 加咖喱。

ts
import { tryit } from "radash";

const findUser = tryit(api.users.find);

const [err, user] = await findUser(userId);