这个例子(repl.it)(来自这个答案)在我看来,它遵循了关于诺言的所有规则。然而,运行它会记录一个有关未处理的承诺拒绝的异常以及相关的控制台消息。(在FF,Chrome和Node v10中也会发生这种情况。)
try / catch块显然在那里并且包装了被拒绝的承诺,那么怎么回事,我将如何解决?
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
调用被拒绝的时候,解释器还没有到达由await
所创建的promise的行rej
,因此被拒绝的Promise就是被拒绝的Promise,而不是当前线程的Promise是await
荷兰国际集团:
try {
const delay1 = res(3000)
const delay2 = res(2000)
const delay3 = rej(1000)
const data1 = await delay1
// The interpreter is paused on the line above when `rej` rejects
const data2 = await delay2
const data3 = await delay3
因此,其行为与声明没有catch
处理程序的被拒绝的Promise相同。(由承诺引发的错误只会在被捕获async
功能,如果他们await
编在处无极拒绝点-否则,它只会导致未处理的承诺拒绝)
我建议您在与您相同的时候声明Promises await
:
const data1 = await res(3000)
(注意:以上方法的计时与原始代码不同)
或使用await Promise.all
对所有的承诺,这意味着Promise
解释目前await
荷兰国际集团将抛出(从而进入catch
块)只要一个承诺废品:
const [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000)
]);
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 [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000),
]);
} catch (error) {
console.log(`error caught: await finished`, Date.now() - start)
}
}
example()
做额外的工作,而三项承诺是持续的,并从这些承诺,以及在主线程捕捉错误,通过一个第四个项目的Promise.all
,已经做了你想要做的额外工作的IIFE:
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 [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000),
(() => {
console.log('doing work...');
})()
]);
} catch (error) {
console.log(`error caught: await finished`, Date.now() - start)
}
}
example()
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句