[英]Unhandled promise rejection?
這個例子(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
rej
創建的承諾的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相同。 (Promises拋出的錯誤只會在async
函數中被捕獲,如果它們await
Promise拒絕的時候 - 否則,它只會導致未處理的promise拒絕。)
我建議你await
它們的同時聲明Promise:
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正在進行時執行額外的工作,並從這些Promise.all
以及主線程中捕獲錯誤,請將第四個項目傳遞給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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.