承诺拒绝,而不考虑在调用方上配置 catch 子句



在本文的上下文中:异步函数。 在"示例"部分中

function resolveAfter2Seconds() {
console.log("starting slow promise")
return new Promise(resolve => {
setTimeout(function() {
resolve("slow")
console.log("slow promise is done")
}, 2000)
})
}
function resolveAfter1Second() {
console.log("starting fast promise")
return new Promise(resolve => {
setTimeout(function() {
resolve("fast")
console.log("fast promise is done")
}, 1000)
})
}
async function concurrentStart() {
console.log('==CONCURRENT START with await==');
const slow = resolveAfter2Seconds() // starts timer immediately
const fast = resolveAfter1Second() // starts timer immediately
// 1. Execution gets here almost instantly
console.log(await slow) // 2. this runs 2 seconds after 1.
console.log(await fast) // 3. this runs 2 seconds after 1., immediately after 2., since fast is already resolved
}

它说:在 concurrentStart 中,如果在 promise slow 实现之前 promise fast 拒绝,那么无论调用方是否配置了 catch 子句,都会引发一个未处理的承诺拒绝错误。

我没有得到它,所以我做了很少的谷歌并找到了这个代码片段:

async function f() {
let response = await fetch('http://no-such-url');
}
// f() becomes a rejected promise
f().catch(alert); // TypeError: failed to fetch // (*)

上面的代码有效,它有一个配置为调用者的 catch 子句。

所以我不明白为什么在承诺拒绝时我们会得到错误??

我唯一能做的观察是,当对应于 resolveAfter1Second(( 的承诺将被拒绝时,函数 concurrentPromise 的执行会因等待 resolveAfter2Seconds(( 的承诺而停止。 但我无法将这一观察结果与文章中的上述陈述联系起来。

这个问题在等待多个并发等待操作和等待 await Promise.all(( 和多个等待之间的任何区别?中得到了更好和更详细的解释。

MDN文章在这里做得不好。警告所指的是当两个调用的函数返回将拒绝的承诺时会发生什么。该方案的正确示例代码是

function rejectAfter2Seconds() {
console.log("creating slow promise")
return new Promise((resolve, reject) => {
setTimeout(function() {
reject("slow error")
console.log("slow promise is broken")
}, 2000)
})
}
function rejectAfter1Second() {
console.log("creating fast promise")
return new Promise((resolve, reject) => {
setTimeout(function() {
reject("fast error")
console.log("fast promise is broken")
}, 1000)
})
}
async function concurrentStart() {
console.log('==CONCURRENT START with await==');
const slow = rejectAfter2Seconds() // starts timer immediately
const fast = rejectAfter1Second() // starts timer immediately
console.log(await slow) // waits two seconds
console.log(await fast) // causes unhandled rejection after one second
}
concurrentStart().catch(err => {
//               ^^^^^^ we can attach an error handler to the promise, but
console.log(err); // it handles only one error
});
window.onunhandledrejection = err => {
console.error(err.reason); // and we still get an unhandled rejection
};

最新更新