lodash已死?radash库方法介绍及源码解析 —— 异步方法篇

在这里插入图片描述

写在前面

tips:点赞 + 收藏 = 学会!

  • 我们前面已经介绍了 radash 的相关信息和所有 Array 相关方法,详情可前往主页查看。
  • 本篇我们继续介绍radash中异步相关的方法。
  • 所有方法分享完毕后,后续作者也会整理出 Radash 库所有方法的使用目录,包括文章说明脑图说明
    • 因为方法较多,后续将专门发布一篇总结文档,方便大家查阅使用。
    • 所有方法的思维导图说明后续也会上传至 github 和 gitee,有需要的可以访问下载。

all:同时执行多个异步操作

  1. 使用说明
    1. 功能描述: 类似于 Promise.allPromise.allSettled,等待一个由多个 Promise 组成的对象或数组中的所有 Promise 都完成(或者其中一个失败)。执行的所有错误和抛出的错误都会收集在 AggregateError 中。
    2. 参数:promise对象/promise数组
    3. 返回值:所有 promise 执行后的结果数组或对象
  2. 使用代码示例
    import { all } from 'radash'
    
    // 传入promise数组
    const [user] = await all([
      api.users.create(...),
      s3.buckets.create(...),
      slack.customerSuccessChannel.sendMessage(...)
    ])
    
    // 传入对象
    const { user } = await all({
      user: api.users.create(...),
      bucket: s3.buckets.create(...),
      message: slack.customerSuccessChannel.sendMessage(...)
    })
    
  3. 源码解析
    // 定义一个泛型异步函数 `all`。
    export async function all<
      // 泛型约束 `T` 可以是一个 `Promise` 数组或一个 `Promise` 对象。
      T extends Record<string, Promise<any>> | Promise<any>[]
    >(promises: T) {
      // 根据 `promises` 是数组还是对象,将其转换成一个统一格式的数组 `entries`。
      const entries = isArray(promises)
        ? promises.map(p => [null, p] as [null, Promise<any>])
        : Object.entries(promises)
    
      // 使用 `Promise.all` 等待所有 `Promise` 完成,并处理每个 `Promise` 的结果和异常。
      const results = await Promise.all(
        entries.map(([key, value]) =>
          value
            .then(result => ({ result, exc: null, key })) // 如果成功,记录结果。
            .catch(exc => ({ result: null, exc, key })) // 如果失败,记录异常。
        )
      )
    
      // 筛选出所有出现异常的结果。
      const exceptions = results.filter(r => r.exc)
      // 如果有异常,抛出一个 `AggregateError`,包含所有异常。
      if (exceptions.length > 0) {
        throw new AggregateError(exceptions.map(e => e.exc))
      }
    
      // 如果输入的 `promises` 是数组,返回一个包含所有结果的数组。
      if (isArray(promises)) {
        return results.map(r => r.result) as T extends Promise<any>[]
          ? PromiseValues<T>
          : unknown
      }
    
      // 如果输入的 `promises` 是对象,将结果组合成一个新对象并返回。
      return results.reduce(
        (acc, item) => ({
          ...acc,
          [item.key!]: item.result // 使用断言 `item.key!`,因为我们知道 `key` 不会是 `null`。
        }),
        {} as { [K in keyof T]: Awaited<T[K]> } // 返回类型是一个对象,其键类型为 `T` 的键,值类型为 `T` 中 `Promise` 解析后的类型。
      )
    }
    
    • 方法流程说明:
      1. 将输入的 promises 转换为一个统一格式的 entries 数组,无论它是一个 Promise 数组还是一个 Promise 对象。
      2. 对于每个 entry,创建一个新的 Promise 来处理成功和失败的情况,并使用 Promise.all 等待所有这些新 Promise 完成。
      3. 如果所有 Promise 都成功解析,根据 promises 是数组还是对象,返回一个包含所有结果的数组或对象。
      4. 如果有一个或多个 Promise 失败,则抛出一个 AggregateError,其中包含所有失败的 Promise 的异常。

defer:在异步流程中添加清理或错误处理逻辑

  1. 使用说明
    1. 功能描述:用来执行一个异步函数,同时提供注册回调的机制,在异步函数执行完成后执行特定回调操作。
    2. 参数:异步函数。
    3. 返回值:异步函数成功执行时,返回其响应结果,否则重新抛出错误。
  2. 使用代码示例
    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)
    })
    
  3. 源码解析
    // 定义一个异步泛型函数 `defer`。
    export const defer = async <TResponse>(
      // `func` 是一个接受注册函数 `register` 的异步函数。
      func: (
        register: (
          // `register` 允许 `func` 注册一个回调函数 `fn`,该函数在 `func` 执行完成后调用。
          // 可以通过 `options` 指定是否在回调函数中重新抛出错误。
          fn: (error?: any) => any,
          options?: 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值