old*_*ard 8 node.js async-await typescript
我想等待两个并行运行的承诺。我不想连续等待每个承诺(这有效但速度较慢)。
出于这个原因,我认为我可以首先创建两个承诺来让它们滚动,比如说两个网络请求,然后等待它们并能够在 catch 块中捕获错误。这个假设似乎是不正确的,因为我在运行此示例代码时收到警告。
async function testMultipleAwait() {
try {
const aPromise = new Promise((resolve) => {
setTimeout(() => resolve('a'), 200);
});
const bPromise = new Promise((_, reject) => {
setTimeout(() => reject('b'), 100);
});
const a = await aPromise;
const b = await bPromise;
} catch (e) {
console.log('Caught error', e);
}
}
testMultipleAwait();
Run Code Online (Sandbox Code Playgroud)
不会导致“捕获错误”输出,而是我得到
tsc test-try-catch-await.ts && node test-try-catch-await.js
(node:31755) UnhandledPromiseRejectionWarning: b
(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)
(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.
Caught error b
(node:31755) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
Run Code Online (Sandbox Code Playgroud)
我想我知道问题是什么。尽管这些承诺以并发方式启动,但您仍在等待aPromise并按bPromise顺序:
const a = await aPromise; // First await this...
const b = await bPromise; // and then start to await this
Run Code Online (Sandbox Code Playgroud)
当这两个承诺都兑现时,这就不是什么大问题了。它会让你等待尽可能多的时间
Promise.all,然后愉快地继续。这就是为什么这个问题根本不那么明显......
重要的是要知道,在底层,由于 async/await,这个 try-catch 被转换为一个承诺。这意味着首先等待的语句之后的任何内容都将最终出现在promise.then 回调函数中。
因此,在到达const b = await bPromise之前(200 毫秒后)不会运行。提前 100 毫秒失败。const abPromise
这并不是说 async/await 不会发现错误或catch完全附加您的块(如promise.catch(...))。毕竟,节点警告和 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)
Run Code Online (Sandbox Code Playgroud)
bPromise所以 de catch 子句确实有效,但异步函数直到至少 200 毫秒后才将其附加到。第 5 行似乎证实了这一点:
PromiseRejectionHandledWarning: Promise rejection was handled asynchronously.
Run Code Online (Sandbox Code Playgroud)
一旦微任务队列为空,就会抛出拒绝错误。
承诺拒绝已处理,但节点认为您已经太晚了。您可以使用 解决此问题Promise.all。这样,您await和您的异步函数将首先捕获每个潜在的错误。
// Everything just as it is.. and then:
const [a, b] = await Promise.all([
aPromise,
bPromise,
]);
Run Code Online (Sandbox Code Playgroud)
因为我很好奇,所以我在 chrome 控制台中输入了您的代码,看看会发生什么。错误日志会在很短的时间内弹出(我猜是 100 毫秒)。看看这个输出,你可以听到 chrome 说:
“啊等等!它终于被抓住了。这是消息!”
| 归档时间: |
|
| 查看次数: |
2395 次 |
| 最近记录: |