簡體   English   中英

未處理的承諾拒絕?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM