news 2026/8/22 15:41:31

5个until-async常见坑点:为什么不能直接传Promise实例?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5个until-async常见坑点:为什么不能直接传Promise实例?

5个until-async常见坑点:为什么不能直接传Promise实例?

【免费下载链接】until-asyncGracefully handle Promises using async/await without try/catch.项目地址: https://gitcode.com/gh_mirrors/un/until-async

until-async 是一个轻量级 JavaScript 工具库,让你用async/await优雅地处理 Promise,无需再写繁琐的try/catch。它把错误和数据打包成[error, data]元组返回,风格与 Node.js 回调 API 一脉相承。但许多新手在使用时会踩进 5 个常见坑点,其中最核心的一个就是:为什么不能直接传一个 Promise 实例?本文将逐一拆解,帮你快速上手。

坑点 1:给 until 直接传 Promise 实例 ⚠️

这是新手最常遇到的疑问。很多人会这样写:

import { until } from 'until-async' // ❌ 错误示范:直接传 Promise const [error, data] = await until(fetchUser(id))

until的签名(见 src/index.ts)明确要求传入一个返回 Promise 的函数

// ✅ 正确写法:传一个函数 const [error, data] = await until(() => fetchUser(id))

原因有两点:

  • 捕获时机问题:Promise 实例在传入until之前就已经被创建。如果fetchUser(id)在返回 Promise 之前就同步抛错(比如参数校验失败),这个错误发生在until的保护范围之外,根本捕获不到。传函数则把整个调用过程都包进 try/catch。
  • 处理"逻辑单元"而非"单个 Promise":这是作者的刻意设计(README 的 FAQ 有详细说明)。一个until调用可以包裹一段复杂的异步逻辑,其中任意一步出错都能被同一个error捕获:
const [error, data] = await until(async () => { const user = await fetchUser() const nextUser = normalizeUser(user) const transaction = await saveModel('user', user) return transaction.result })

如果只接受 Promise 实例,这种"一次调用管一整段逻辑"的能力就完全无从实现。

坑点 2:忘记先判断 error 就直接用 data

until不会帮你抛错,它只是把结果打包返回。如果你跳过判断直接使用数据:

const [error, data] = await until(() => fetchUser(id)) // ❌ error 存在时 data 是 null,这里会直接崩 return data.name

最快避错方法:始终先写if (error)分支,形成肌肉记忆。元组保证了两者的互斥关系——要么有错误,要么有数据。

坑点 3:TypeScript 自定义错误忘了显式标注类型

until的泛型默认把错误类型推断为Error(见 src/until.test-d.ts 中的类型测试)。如果你的接口 reject 的是自定义错误对象(比如{ type: 'NOT_FOUND' }),不做显式标注的话,error.type在 TS 里会报错:

// ✅ 显式声明错误类型和数据类型 const [error, data] = await until<UserFetchError, User>(() => fetchUser(id))

而一旦标注了类型,TypeScript 会把它当作"可辨识联合类型"处理:if (error)分支里data自动收窄为null,else 分支里error收窄为null,体验非常顺滑。

坑点 4:把 data 当成"一定存在"的变量

很多来自回调式写法的开发者会下意识地给data设初始值或加兜底:

// ❌ 多余的防御代码 const data = (result[1] ?? {}).name

until返回的元组类型(UntilResult,定义在 src/index.ts)已经用类型系统强制表达了"错误与数据互斥"。正确姿势是信任类型,写清晰的两分支逻辑即可,兜底代码反而会掩盖真实问题。

坑点 5:记反元组顺序——是 [error, data],不是 [data, error]

until遵循 Node.js 回调的约定:错误永远排第一

const [error, data] = await until(() => Promise.resolve(123)) // error === null, data === 123

顺手记法:看到until就联想 "until 出错为止",所以 error 在前。写反了解构顺序不会报错,但会导致静默的 null 数据事故,是最隐蔽的坑。

快速安装与验证

通过 npm 安装即可使用:

npm install until-async

如果你克隆了源码仓库,可以运行pnpm test查看 src/until.test.ts 中的行为测试(正常值、reject 错误、自定义 reject 值都被覆盖),类型层面的保证则写在 src/until.test-d.ts 中。项目构建与发布配置分别位于 tsdown.config.ts 和 package.json。

小结

坑点一句话记忆
传 Promise 实例只传函数,让 try/catch 包住整个逻辑单元
不判断 error永远if (error)先行
自定义错误显式泛型until<MyError, Data>
兜底 data信任元组类型,写两分支
元组顺序错误在前:[error, data]

掌握这 5 个要点,until-async 就能成为你项目中替代 try/catch 的优雅选择。

【免费下载链接】until-asyncGracefully handle Promises using async/await without try/catch.项目地址: https://gitcode.com/gh_mirrors/un/until-async

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/22 15:40:16

OBS 多RTMP同时配信插件完全指南:一次编码,推流多个平台

OBS 多RTMP同时配信插件完全指南&#xff1a;一次编码&#xff0c;推流多个平台 【免费下载链接】obs-multi-rtmp OBS複数サイト同時配信プラグイン 项目地址: https://gitcode.com/gh_mirrors/ob/obs-multi-rtmp obs-multi-rtmp 是一款免费开源的 OBS 多平台同时推流插…

作者头像 李华
网站建设 2026/8/22 15:37:39

Vue 文档编辑器快速上手:5 分钟搭好纸面式在线文档编辑页

Vue 文档编辑器快速上手&#xff1a;5 分钟搭好纸面式在线文档编辑页 【免费下载链接】vue-document-editor :page_facing_up: Paper-sized WYSIWYG document editor for Vue apps 项目地址: https://gitcode.com/gh_mirrors/vu/vue-document-editor vue-document-edito…

作者头像 李华
网站建设 2026/8/22 15:36:00

彻底卸载 Visual Studio 2015,清空残留文件

彻底卸载 Visual Studio 2015&#xff0c;清空残留文件 【免费下载链接】VisualStudioUninstaller Visual Studio Uninstallation sometimes can be unreliable and often leave out a lot of unwanted artifacts. Visual Studio Uninstaller is designed to thoroughly and re…

作者头像 李华