I think我知道问题是什么。尽管承诺同时开始,但您仍在等待aPromise
and bPromise
依次:
const a = await aPromise; // First await this...
const b = await bPromise; // and then start to await this
当这两个承诺都兑现时,这就不是什么大问题了。它会让你等待尽可能多的时间Promise.all
会,然后愉快地继续。这就是为什么这个问题根本不那么明显......
重要的是要知道,在底层,由于 async/await,这个 try-catch 被转换为一个承诺。这意味着首先等待的语句之后的任何内容都将最终出现在promise.then 回调函数中。
So, const b = await bPromise
之前不会运行const a
已到达(200 毫秒后)。bPromise
提前 100 毫秒失败。
这并不是说 async/await 不会发现错误或附加您的catch
完全阻止(如promise.catch(...))。毕竟,有is节点警告和 catch 处理程序的终端输出:
tsc test-try-catch-await.ts && node test-try-catch-await.js
1 first node sees the error > (node:31755) UnhandledPromiseRejectionWarning: b
2 (node:31755) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
3 (node:31755) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
4 and then your catch handler > Caught error b
5 (node:31755) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
所以 de catch 子句确实有效,但 async 函数不会费心将其附加到bPromise
直到至少 200 毫秒后。第 5 行似乎证实了这一点:
PromiseRejectionHandledWarning: Promise rejection was handled asynchronously.
一旦出现拒绝错误就会抛出微任务队列是空的。
承诺拒绝已处理,但节点认为您已经太晚了。您可以使用以下方法解决此问题Promise.all。这样你await
一旦,你的异步函数将首先捕获每个潜在的错误。
// Everything just as it is.. and then:
const [a, b] = await Promise.all([
aPromise,
bPromise,
]);
因为我很好奇,所以我在 chrome 控制台中输入了您的代码,看看会发生什么。错误日志会在很短的时间内弹出(我猜是 100 毫秒)。看看这个输出,你可以听到 chrome 说:
“啊等等!它终于被抓住了。这是消息!”
点击查看 gif 动画。