Promise.try()
Promise.try()
静态方法接受任何类型的回调(同步或异步返回或抛出),并将结果包装在 Promise
中。
语法
Promise.try(func)
参数
func
-
一个同步调用且没有参数的函数。它可以执行任何操作——返回一个值、抛出一个错误或返回一个 Promise。
返回值
一个 Promise
,它
- 如果
func
同步返回一个值,则已完成。 - 如果
func
同步抛出一个错误,则已拒绝。 - 如果
func
返回一个 Promise,则异步完成或拒绝。
描述
您可能有一个采用回调的 API。回调可能是同步的或异步的。您希望通过将结果包装在 Promise 中来统一处理所有内容。最直接的方法可能是 Promise.resolve(func())
。问题是,如果 func()
同步抛出一个错误,则不会捕获此错误并将其转换为已拒绝的 Promise。正确的做法如下,Promise.try(func)
与之完全等效
new Promise((resolve) => resolve(func()));
除了 Promise.try()
可能更简洁易读之外。更准确地说,以下是 Promise.try()
实现的更忠实的表示(尽管它仍然不应作为 polyfill 使用)
new Promise((resolve, reject) => {
try {
resolve(func());
} catch (error) {
reject(error);
}
});
对于内置的 Promise()
构造函数,从执行器抛出的错误会自动捕获并转换为拒绝,因此这两个示例是等效的。
请注意,Promise.try()
不等效于此,尽管非常相似
Promise.resolve().then(func);
区别在于传递给 then()
的回调始终异步调用,而 Promise()
构造函数的执行器同步调用。Promise.try
也会同步调用该函数,并在可能的情况下立即解析 Promise。
Promise.try()
结合 catch()
和 finally()
,可以用于在一个链中处理同步和异步错误,并使 Promise 错误处理看起来几乎像同步错误处理。
示例
使用 Promise.try()
以下示例接受一个回调,“提升”到 Promise 中,处理结果并进行一些错误处理
function doSomething(action) {
return Promise.try(action)
.then((result) => console.log(result))
.catch((error) => console.error(error))
.finally(() => console.log("Done"));
}
doSomething(() => "Sync result");
doSomething(() => {
throw new Error("Sync error");
});
doSomething(async () => "Async result");
doSomething(async () => {
throw new Error("Async error");
});
在 async/await 中,相同的代码如下所示
async function doSomething(action) {
try {
const result = await action();
console.log(result);
} catch (error) {
console.error(error);
} finally {
console.log("Done");
}
}
在非 Promise 构造函数上调用 try()
Promise.try()
是一个泛型方法。它可以在任何实现与 Promise()
构造函数相同签名的构造函数上调用。例如,我们可以将其调用在一个将 console.log
作为 resolve
和 reject
函数传递给 executor
的构造函数上
class NotPromise {
constructor(executor) {
// The "resolve" and "reject" functions behave nothing like the native
// promise's, but Promise.try() just calls resolve
executor(
(value) => console.log("Resolved", value),
(reason) => console.log("Rejected", reason),
);
}
}
const p = Promise.try.call(NotPromise, () => "hello");
// Logs: Resolved hello
const p2 = Promise.try.call(NotPromise, () => {
throw new Error("oops");
});
// Logs: Rejected Error: oops
规范
规范 |
---|
Promise.try # sec-promise.try |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。