Javascript 未经处理的拒绝承诺?
在我看来,它遵守了所有关于承诺的规则。但是,运行它会记录一个异常,该异常与未处理的承诺拒绝有关,并带有相关的控制台消息。(这也发生在FF、Chrome和节点v10中。) try/catch块显然就在那里,它包装了被拒绝的承诺,那么发生了什么,我该如何修复它呢Javascript 未经处理的拒绝承诺?,javascript,promise,async-await,Javascript,Promise,Async Await,在我看来,它遵守了所有关于承诺的规则。但是,运行它会记录一个异常,该异常与未处理的承诺拒绝有关,并带有相关的控制台消息。(这也发生在FF、Chrome和节点v10中。) try/catch块显然就在那里,它包装了被拒绝的承诺,那么发生了什么,我该如何修复它呢 async function example() { const start = Date.now() let i = 0 function res(n) { const id = ++i return new
async function example() {
const start = Date.now()
let i = 0
function res(n) {
const id = ++i
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
console.log(`res #${id} called after ${n} milliseconds`, Date.now() - start)
}, n)
})
}
function rej(n) {
const id = ++i
return new Promise((resolve, reject) => {
setTimeout(() => {
reject()
console.log(`rej #${id} called after ${n} milliseconds`, Date.now() - start)
}, n)
})
}
try {
const delay1 = res(3000)
const delay2 = res(2000)
const delay3 = rej(1000)
const data1 = await delay1
const data2 = await delay2
const data3 = await delay3
} catch (error) {
console.log(`await finished`, Date.now() - start)
}
}
example()
问题是,在
rej
调用拒绝时,解释器尚未到达等待s由rej
创建的承诺的行,因此被拒绝的承诺只是被拒绝的承诺,而不是当前线程正在等待的承诺:
因此,该行为与在没有catch
处理程序的情况下声明被拒绝的承诺相同。(承诺抛出的错误只有在承诺拒绝时被async
函数捕获,否则,它只会导致未经处理的承诺拒绝。)
我建议要么在等待承诺的同一时间宣布承诺:
const data1 = await res(3000)
(注意:上述方法的计时将与原始代码不同)
或者使用wait Promise.all
表示所有承诺,这意味着解释器当前正在等待的Promise将在其中一个承诺被拒绝时立即抛出(从而进入catch
块):
const [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000)
]);
异步函数示例(){
const start=Date.now()
设i=0
函数res(n){
常量id=++i
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
解决()
log(${n}毫秒之后调用的`res}${id},Date.now()-start)
},n)
})
}
函数rej(n){
常量id=++i
返回新承诺((解决、拒绝)=>{
设置超时(()=>{
拒绝
log(${n}毫秒之后调用'rej}${id},Date.now()-start)
},n)
})
}
试一试{
const[data1,data2,data3]=等待承诺。全部([
res(3000),
res(2000年),
雷杰(1000),
]);
}捕获(错误){
log(`error capture:await finished`,Date.now()-start)
}
}
example()
将调用与原始示例中的wait
分开,这样可以在异步工作时完成一些事情。似乎您是在说,如果不使用.catch()
,就不可能进行这种分离。如果您想在捕获三个承诺抛出的错误的同时做其他事情,请使用承诺。all
方法(加上第四个非承诺,它可以执行您想执行的任何其他操作),请参见编辑。除了}catch
const [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000)
]);