我在浏览器和 node.js 中试过了。我得到一个
Uncaught (in promise) Error: here
...我不知道为什么try catch不能得到它。
有人能解开这个谜吗?
fct = async (msg) => {
throw new Error(msg)
}
delayedValue = (value) => new Promise((resolve) => setTimeout(() => resolve(value), 1000));
(async () => {
try {
console.log(await Promise.all([
fct(await delayedValue('here')),
fct(await delayedValue('it is')),
]));
} catch (e) {
console.error('catched', e);
}
})();
问题是
await
s 和 un-await
ed 异步函数调用的组合。代码执行为
const value1 = await delayedValue('here');
const promise1 = fct(value1);
const value2 = await delayedValue('it is');
const promise2 = fct(value2);
await Promise.all([promise1, promise2]);
promise1
是一个在通过 Promise.all
附加处理程序1之前被拒绝的承诺。当
delayedValue('it is')
承诺被 await
ed 时,它已经被拒绝了,这会导致未处理的拒绝错误。
不清楚您希望代码如何运行,您可能正在寻找任何
const value1 = await delayedValue('here');
const value2 = await fct(value1);
const value3 = await delayedValue('it is');
const value4 = await fct(value3);
console.log([value2, value4]);
const [value1, value2] = await Promise.all([
delayedValue('here'),
delayedValue('it is'),
]);
console.log(await Promise.all([
fct(value1),
fct(value2),
]));
console.log(await Promise.all([
delayedValue('here').then(fct),
delayedValue('it is').then(fct),
]));
const value1 = await delayedValue('here');
const [value2, value4] = await Promise.all([
fct(value1),
delayedValue('it is').then(fct)
]);
console.log([value2, value4]);
所有这些都将快速失败,并立即在周围的
try
/catch
块中处理来自任何被调用函数的任何错误。
1:更准确地说,处理程序必须在同一个微任务(循环?)期间“立即”附加,可能是在承诺被拒绝之后——当
fct()
返回一个已经被拒绝的承诺时就可以了。无论哪种方式,await delayedValue()
在附加拒绝处理程序之前都是不可接受的。
在
fct(await delayedValue('here'))
中,await
使IIFE等待delayedValue('here')
1秒,然后将'here'
传递给fct()
,这又会引发错误。
在事件循环的这个时候,
await delayedValue('it is')
还没有返回任何东西,这意味着IIFE还在等待它,还没有执行catch
.
话虽这么说,
catch
最终发现了错误,但晚了一秒钟。