这在很大程度上是一个意见问题。无论您做什么,都要始终如一地进行,并清楚地记录下来。
我可以给你的一条客观信息是,这是 JavaScriptasync
函数设计中经常讨论的主题,你可能知道这些函数隐式地返回了对它们的工作的Promise。您可能还知道第一个async
函数之前的部分await
或者return
是同步的;它仅在它await
s 或返回时才变为异步。
TC39 最后决定即使是在async
函数的同步部分抛出的错误也应该拒绝其Promise而不是引发同步错误。例如:
async function someAsyncStuff() {
return 21;
}
async function example() {
console.log("synchronous part of function");
throw new Error("failed");
const x = await someAsyncStuff();
return x * 2;
}
try {
console.log("before call");
example().catch(e => { console.log("asynchronous:", e.message); });
console.log("after call");
} catch (e) {
console.log("synchronous:", e.message);
}
在那里你可以看到,即使在函数throw new Error("failed")
的同步部分,它也拒绝Promise而不是引发同步错误。
即使对于在函数体中的第一条语句之前发生的事情也是如此,例如确定缺少的函数参数的默认值:
async function someAsyncStuff() {
return 21;
}
async function example(p = blah()) {
console.log("synchronous part of function");
throw new Error("failed");
const x = await Promise.resolve(42);
return x;
}
try {
console.log("before call");
example().catch(e => { console.log("asynchronous:", e.message); });
console.log("after call");
} catch (e) {
console.log("synchronous:", e.message);
}
这失败了,因为blah
当它运行代码以获取p
我在调用中未提供的参数的默认值时,它尝试调用不存在的 。如您所见,即使这样也会拒绝Promise而不是抛出同步错误。
TC39 可以走另一条路,让同步部分引发同步错误,就像这个非async
函数所做的那样:
async function someAsyncStuff() {
return 21;
}
function example() {
console.log("synchronous part of function");
throw new Error("failed");
return someAsyncStuff().then(x => x * 2);
}
try {
console.log("before call");
example().catch(e => { console.log("asynchronous:", e.message); });
console.log("after call");
} catch (e) {
console.log("synchronous:", e.message);
}
但他们经过讨论后决定采用一致的Promise拒绝。
因此,这是您在决定如何在您自己的async
执行异步工作的非函数中处理此问题时需要考虑的具体信息。