写在前面
tips:点赞 + 收藏 = 学会!
- 我们前面已经介绍了
radash
的相关信息和所有Array
相关方法,详情可前往主页查看。 - 本篇我们继续介绍radash中异步相关的方法。
- 所有方法分享完毕后,后续作者也会整理出
Radash
库所有方法的使用目录,包括文章说明和脑图说明。- 因为方法较多,后续将专门发布一篇总结文档,方便大家查阅使用。
- 所有方法的思维导图说明后续也会上传至 github 和 gitee,有需要的可以访问下载。
all:同时执行多个异步操作
- 使用说明
- 功能描述: 类似于
Promise.all
和Promise.allSettled
,等待一个由多个Promise
组成的对象或数组中的所有Promise
都完成(或者其中一个失败)。执行的所有错误和抛出的错误都会收集在AggregateError
中。 - 参数:promise对象/promise数组
- 返回值:所有
promise
执行后的结果数组或对象
- 功能描述: 类似于
- 使用代码示例
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(...) })
- 源码解析
// 定义一个泛型异步函数 `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` 解析后的类型。 ) }
- 方法流程说明:
- 将输入的
promises
转换为一个统一格式的entries
数组,无论它是一个Promise
数组还是一个Promise
对象。 - 对于每个
entry
,创建一个新的Promise
来处理成功和失败的情况,并使用Promise.all
等待所有这些新Promise
完成。 - 如果所有
Promise
都成功解析,根据promises
是数组还是对象,返回一个包含所有结果的数组或对象。 - 如果有一个或多个
Promise
失败,则抛出一个AggregateError
,其中包含所有失败的Promise
的异常。
- 将输入的
- 方法流程说明:
defer:在异步流程中添加清理或错误处理逻辑
- 使用说明
- 功能描述:用来执行一个异步函数,同时提供注册回调的机制,在异步函数执行完成后执行特定回调操作。
- 参数:异步函数。
- 返回值:异步函数成功执行时,返回其响应结果,否则重新抛出错误。
- 使用代码示例
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) })
- 源码解析
// 定义一个异步泛型函数 `defer`。 export const defer = async <TResponse>( // `func` 是一个接受注册函数 `register` 的异步函数。 func: ( register: ( // `register` 允许 `func` 注册一个回调函数 `fn`,该函数在 `func` 执行完成后调用。 // 可以通过 `options` 指定是否在回调函数中重新抛出错误。 fn: (error?: any) => any, options?: