Our*_*rus 4 javascript promise async-await
这个例子(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()
Run Code Online (Sandbox Code Playgroud)
问题是,在rej
调用拒绝的时候,解释器还没有得到一个await
由创建的承诺的行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
Run Code Online (Sandbox Code Playgroud)
因此,行为与在没有catch
处理程序的情况下声明被拒绝的Promise相同.(由承诺引发的错误只会在被捕获async
功能,如果他们await
编在处无极拒绝点 -否则,它只会导致未处理的承诺拒绝)
我建议你或者在同一点声明Promise await
:
const data1 = await res(3000)
Run Code Online (Sandbox Code Playgroud)
(注意:上述方法的时间与原始代码不一样)
或使用await Promise.all
对所有的承诺,这意味着Promise
解释目前await
荷兰国际集团将抛出(从而进入catch
块)只要一个承诺的拒绝:
const [data1, data2, data3] = await Promise.all([
res(3000),
res(2000),
rej(1000)
]);
Run Code Online (Sandbox Code Playgroud)
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()
Run Code Online (Sandbox Code Playgroud)
做额外的工作,而三项承诺是持续的,并且赶上从这些承诺,以及在主线程错误,传递第四个项目的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()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
389 次 |
最近记录: |