Mic*_*ler 5 node.js async-await
我正在阅读MDN 上描述的“for wait of循环” 。它看起来令人印象深刻,所以我玩了一些代码,但令人惊讶的是我无法捕获那里抛出的错误。
'use strict';
const main = async() => {
const bar = [];
bar.push(new Promise((res) => { setTimeout(() => res(1), 1200); }));
bar.push(new Promise((res) => { setTimeout(() => res(2), 800); }));
bar.push(new Promise((res, rej) => { setTimeout(() => rej(3), 200); }));
try {
for await (const foo of bar) {
console.log('hey', foo);
}
} catch (err) {
console.error('err', err);
}
};
main();
Run Code Online (Sandbox Code Playgroud)
我的输出主要是像我预期的那样。但我不明白,为什么我会收到 UnhandledPromiseRejection?我什至没有发现那个错误吗?
$> node await-loop.js
(node:10704) UnhandledPromiseRejectionWarning: 3
(node:10704) 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:10704) [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.
hey 1
hey 2
err 3
(node:10704) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1)
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解并在这里写一个正确的口号吗?我错过了什么吗?
未处理的 Promise 拒绝?
我什至没有发现那个错误吗?
理论上是的。(这就是 catch 块的用途,对吧?)
从技术上讲没有。
Main Stack
| try |
| |
| await bar[0] | <-- waiting to resolve till sometime after 1200
| |
| catch |
| |
Run Code Online (Sandbox Code Playgroud)
(大约)200 毫秒后:
bar[2] 被拒绝并推送到队列,但 wait 没有屈服,因为它仍在等待 bar[0] 屈服,这仅在 1200 毫秒后发生
因此,在 bar[2] 被拒绝时,没有catch可用的块来处理rejected promise. 请参阅上面的堆栈并注意,在拒绝时,try..catch和bar[2]不在同一个堆栈中,至少对于编译器而言(或概念上对于 javascript)。
但你注意到:err 3当finally等待产生时,catch块捕获了哪些内容bar[2]
如果您更改承诺的顺序并将被拒绝的承诺作为数组中的第一项,您将看到 catch 块运行良好。
或者等待不同的情况:
// unhandled rejection
try {
await bar[0]
await bar[1]
await bar[2]
} catch (e) {
console.error('error', e)
}
// Catch successfull
try {
await bar[2]
await bar[0]
await bar[1]
} catch (e) {
console.error('error', e)
}
Run Code Online (Sandbox Code Playgroud)
更新:
更好的方法是使用Promise.all,它具有快速失败的行为。
try {
const datas = await Promise.all(bar)
} catch (e) {
console.error(e)
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2423 次 |
| 最近记录: |