拓冰建站拓冰建站
首页 / 资讯中心 / 正文

until-async源码深度剖析:仅20行代码如何实现Promise错误捕获

until-async源码深度剖析仅20行代码如何实现Promise错误捕获【免费下载链接】until-asyncGracefully handle Promises using async/await without try/catch.项目地址: https://gitcode.com/gh_mirrors/un/until-asyncasync/await 让 Promise 的处理变得优雅但await关键字却始终没有提供标准的错误捕获机制try/catch 难以避免。until-async是一个轻量级工具库仅用 26 行源码就解决了「Promise 错误捕获」这一痛点。本文带你通读它的完整源码讲清楚如何用元组返回实现 Node.js 风格错误处理、TypeScript 类型如何设计以及背后的 API 设计巧思。 为什么 Promise 错误捕获需要辅助库ES2017 引入 async/await 后.then().catch()的 Promise 链时代结束了但隐藏成本也随之而来await本身没有任何标准错误处理 API。如果异步操作抛出错误而未被捕获整个函数作用域会直接终止。常见方案对比方案优点痛点Promise.catch()显式处理错误退回回调风格丢失 await 优雅性try/catch包裹await语义标准每处异步操作都要包一层成功/失败逻辑被拆成两个分支冗长易遗漏元组返回until-async错误与数据同作用域需要一行解构语法 核心剖析源码到底写了什么until-async 的全部源码集中在src/index.ts一个文件里有效逻辑只有两部分一个类型定义 一个函数。export type UntilResultRejectionReason, ResolveData | [reason: RejectionReason, data: null] | [reason: null, data: ResolveData] export async function untilRejectionReason Error, ResolveData unknown( callback: () PromiseResolveData, ): PromiseUntilResultRejectionReason, ResolveData { try { const data await callback().catch((error) { throw error }) return [null, data] } catch (error: any) { return [error, null] } }代码可以拆成三层来理解1️⃣ 类型层互斥元组UntilResult是一个二元组只有两种互斥形态形态错误数据[reason, null]✅ 有值恒为null[null, data]恒为null✅ 有值这正是 Node.js 回调风格的「error-first」约定但在这里被做成了完全类型安全的形态。2️⃣ 执行层一层 try/catch 兜住所有错误函数体只用一层try/catch包住await callback()。无论是同步抛出异常还是 Promise 被 reject都会统一落入 catch 分支以[error, null]的形式返回错误从此不会「泄漏」。3️⃣ 返回层统一元组出口成功返回[null, data]失败返回[error, null]。无论走哪条路径出口都只有一个——调用方直接解构即可分支判断只需一个if (error)。其中.catch((error) { throw error })初看略显冗余它的作用是确保 Promise 的 rejection 错误与同步抛出的异常走同一条 catch 通道语义上更清晰。 关键设计为什么接收函数而不是 Promise这是源码中容易被忽略、却最精妙的一处决策README 的 FAQ 中也专门解释了这一点若直接接收 Promise只能捕获单个 Promise的错误接收函数则一次until调用可以包裹整个逻辑单元多个await串行操作、同步的校验逻辑如 invariant 断言、数据转换……内部任何一环抛出异常都会通过同一个error统一返回。也就是说你可以把十几行的复杂异步流程整体塞进until而不用给每个await单独套 try/catch。️ TypeScript 设计可辨识联合 类型推断类型测试位于src/until.test-d.ts验证了两项核心能力自动推断不传类型参数时error与data的类型由回调返回值自动推导可辨识联合discriminated union在if (error)分支内编译器知道data必然是nullelse分支中data则是具体业务类型——无需任何as断言。配合untilRejectionReason, ResolveData两个类型参数你还能精确声明错误的结构例如{ type: NOT_FOUND }IDE 在处理错误时全程智能提示。 测试与工程小而完整整个项目「一个功能两种测试」工程结构非常克制src/until.test.ts— 运行时测试覆盖「成功返回值 / Promise reject / 自定义 reject 原因」等场景src/until.test-d.ts— 类型测试由 vitest 的 typecheck 模式驱动tsdown.config.ts— 构建产物为 ESM同时输出.d.ts类型声明与 sourcemappackage.json—零运行时依赖exports 只暴露单一入口零依赖zero dependency 极小产物体积意味着它可以无负担地进入任何前端或 Node.js 项目。 快速上手两步用上 until-async第 1 步安装npm install until-async第 2 步替换 try/catchimport { until } from until-async const [error, data] await until(() fetchUser(id)) if (error) { return handleError(error) } // 之后放心使用 data错误与数据回到同一个作用域逻辑不再散落在 try/catch 的两个分支里。 总结解决一个痛点await 必须配合 try/catch 做错误捕获的繁琐问题实现仅三层互斥元组类型 一层 try/catch 统一元组返回API 巧思接收函数而非 Promise一次调用兜住整个逻辑单元类型安全可辨识联合保证 error 与 data 二者至多一个非空工程素养零依赖、ESM 单一入口运行时测试与类型测试齐全对于经常被零散 try/catch 困扰的开发者读懂这 26 行源码就掌握了「元组返回错误处理」的核心思想——这套模式你甚至可以花 5 分钟自己写一个。【免费下载链接】until-asyncGracefully handle Promises using async/await without try/catch.项目地址: https://gitcode.com/gh_mirrors/un/until-async创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门