3 回答
TA贡献1865条经验 获得超7个赞
首先,让我们退后一步,一起删除等待:
const main = async () => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time))
try {
const p1 = Stop(500).then(() => { throw new Error('Error ocurred') })
const p2 = Stop(1000)
} catch (err) {
console.log('error catched')
}
main()
我们得到一个未捕获的(承诺的)错误。这是预期的,因为 try/catch 不应该处理 Promise 拒绝。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await#Description
await 表达式导致异步函数执行暂停,直到 Promise 被解决(即完成或拒绝),并在完成后恢复执行异步函数。恢复时,await 表达式的值是已完成的 Promise 的值。
如果 Promise 被拒绝,则 await 表达式会抛出被拒绝的值。
因此,如果我们希望 try/catch 处理 Promise 拒绝,我们需要记住两件事:
我们需要调用
await
以便当 Promise 被拒绝时表达式将抛出(避免未捕获(在 Promise 中)错误)我们必须
await
在 Promise 拒绝发生之前调用
我们可以通过添加我们的第一个 await 来看到这一点:
const main = async () => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time))
try {
const p1 = Stop(500).then(() => { throw new Error('Error ocurred') })
const p2 = Stop(1000)
await p1
} catch (err) {
console.log('error catched')
}
}
main()
现在,await一旦 Promise 拒绝,这将抛出并且我们避免了 Uncaught (in Promise) Error。
但是如果我们添加await p2before await p1,调用p1 Promise期间await p2和之前的拒绝await p1。try/catch 不能及时工作,我们无法正确处理 Promise 拒绝:
const main = async () => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time))
try {
const p1 = Stop(500).then(() => { throw new Error('Error ocurred') })
const p2 = Stop(1000)
await p2
await p1
} catch (err) {
console.log('error catched')
}
}
main()
我们可以通过改变时间来进一步观察 await 的这个关键序列,以便及时await p2恢复函数的执行以await p1等待被调用,从而使 try/catch 等待await p1抛出。
const main = async () => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time))
try {
// Increased the time for p1 so the Promise resolves after p2 Promise resolves
const p1 = Stop(1500).then(() => { throw new Error('Error ocurred') })
const p2 = Stop(1000)
await p2
await p1
} catch (err) {
console.log('error catched')
}
}
main()
我建议使用Promise.all:
更容易捕捉那些烦人的错误
避免每次使用 await 时多次暂停(这不是您的代码片段的问题,因为p1 Promise和p2 Promise正在“并行”运行,但这是代码中常见的问题)
const main = async () => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time))
try {
const p1 = Stop(500).then(() => { throw new Error('Error ocurred') })
const p2 = Stop(1000)
await Promise.all([p2, p1])
} catch (err) {
console.log('error catched')
}
}
main()
TA贡献1848条经验 获得超2个赞
我稍微修改了您的代码,它按预期工作。
const main = async () => {
const Stop = (time) => new Promise((resolve) =>
setTimeout(resolve, time) )
try {
const p1 = new Stop(500).then(() => { throw new Error('Error ocurred') })
const p2 = new Stop(1000)
await p2
await p1
} catch (err) {
console.log('error catched')
}}
main()
我的理解是 Stop 之前指的是同一个实例,当我使用 new 关键字时,它创建了 2 个单独的实例来解决问题
TA贡献1865条经验 获得超7个赞
问题在于 async/await 旨在按时间启动异步任务并等待其执行,而在您的代码片段中您同时启动两个异步任务。如果在等待一个任务执行完成时另一个任务抛出,你会得到Uncaught (in promise) Error.
async/await 的一个很好的用法如下:
const main = async() => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time));
try {
const p1 = await Stop(500).then(() => { throw new Error('Error ocurred') });
const p2 = await Stop(1000);
} catch (err) {
console.log('caught:', err.message)
}
}
main()
但是这两个任务是顺序执行的。处理更多并发异步任务的正确方法是Promise.all:
const main = async() => new Promise((resolve, reject) => {
const Stop = (time) => new Promise((resolve) => setTimeout(resolve, time));
const p1 = Stop(1000).then(() => {
throw new Error('Error ocurred')
});
const p2 = Stop(3000);
Promise.all([p1, p2]).then(resolve).catch(reject);
});
const parent = async() => {
const start = new Date().getTime();
try {
console.log(await main());
} catch (err) {
console.log("caught:", err.message, "after:", new Date().getTime() - start, "ms");
}
};
parent();
添加回答
举报