原文:https://pawelgrzybek.com/promise-try-to-improve-error-handling-and-sync-async-interoperability/
作者:Paweł Grzybek
译者:ChatGPT 4 Turbo
编者注:Promise.try 可接收同步或异步函数,然后做统一的错误处理。这等同于 new Promise(resolve => resolve(f()))
,相比 Promise.resolve().then(f)
会少浪费一个 tick。
几个月前,我发表了一篇 “Deferred JavaScript promises using Promise.withResolvers
” 的文章,解释了一种现代的方式来处理自 JavaScript Promises 以来就存在的一项繁琐工作。随着规范增加简化程序的特性,今天我们来谈谈即将到来的 Promise.try
,它正在快速通过 ECMAScript 提案阶段。
假设我们有两个函数,一个返回 promise,另一个同步返回值,我们可以这样混合使用它们:
const retSync = () => "sync return";
const retAsync = () => new Promise((r) => r("async return"));
(async () =>
retAsync()
.then(console.log)
.then(retSync)
.then(console.log)
.catch(console.error))();
// async return
// sync return
我们换一下顺序,先放一个同步函数。
// 🚨 这行不通
const retSync = () => "sync return";
const retAsync = () => new Promise((r) => r("async return"));
(async () =>
retSync()
.then(console.log)
.then(retAsync)
.then(console.log)
.catch(console.error))();
// TypeError: retSync().then 不是一个函数。(在 'retSync().then(console.log)' 中,'retSync().then' 是 undefined)
我们不能那么做,因为 retSync
的返回值不是一个 thenable promise。我们需要将同步返回的函数包裹在一个 promise 中。
const retSync = () => "sync return";
const retAsync = () => new Promise((r) => r("async return"));
(async () =>
Promise.resolve()
.then(retSync)
.then(console.log)
.then(retAsync)
.then(console.log)
.catch(console.error))();
// sync return
// async return
这样可以运行,但我们浪费了一个事件循环周期。不过,有办法解决这个问题!
const retSync = () => "sync return";
const retAsync = () => new Promise((r) => r("async return"));
(async () =>
new Promise((resolve) => resolve(retSync()))
.then(console.log)
.then(retAsync)
.then(console.log)
.catch(console.error))();
// sync return
// async return
最后,但这不是很累人吗?如果能在不关心事物是同步还是异步的情况下混合使用它们,那就太棒了。此外,一个常见的 catch
子句用于在一个地方处理错误,无需为同步和异步执行分别编写错误处理代码是很方便的。
生态系统中已经有很多解决方案: p-try
来自 Sindre Sorhus、Bluebird Promise.try
/Promise.attempt
或 es6-promise-try
,仅举几例。另外,还有一个原生的 Promise.try
正在 ECMAScript 提案阶段中推进,我相信它很快就会成为语言规范的一部分。
const retSync = () => "sync return";
const retAsync = () => new Promise((r) => r("async return"));
(async () =>
Promise.try(retSync)
.then(console.log)
.then(retAsync)
.then(console.log)
.catch(console.error))();
// sync return
// async return
希望这篇文章帮助你理解了 Promise.try
想要解决的目的和类型问题。继续编码,下次我会 catch("you")
👋