簡體   English   中英

Node.js:未處理的承諾拒絕 - UnhandledPromiseRejectionWarning

[英]Node.js: Unhandled promise rejection - UnhandledPromiseRejectionWarning

我有一個 Node.js 應用程序。 這個應用程序有一個按鈕來啟動一個進程。 該過程中的步驟返回承諾。 我試圖將這些承諾聯系在一起。 出於某種原因,我收到了UnhandledPromiseRejectionWarning 但是,在我看來,我已經正確設置了它。 我的代碼如下所示:

var myButton = document.getElementById('myButton');
if (myButton) {
  console.log('here');
  myButton.addEventListener('click', executeAction('0'));
}

function executeAction(input) {      
  let param1 = 'A';
  let promise = new Promise(function(resolve, reject) {
    try {
      executeStep1()
        .then(result => executeStep2(param1, result, input))
        .then(result => function(result) {
           console.log('All done');
           resolve(result);
        })
        .catch(err => reject(err))
      ;
    } catch (ex) {
      reject(ex);
    }
  });
  return promise;     
}

function executeStep1() {
  let promise = new Promise(function(resolve, reject) {        
    try {
      setTimeout(function() {
        resolve('[something]');
      }, 3000);
    } catch (ex) {
      reject();
    }
  });
  return promise;
}

function executeStep2(p1, p2, p3) {
  let promise = new Promise(function(resolve, reject) {        
    try {
      setTimeout(function() {
        console.log('step 2 has executed');
        resolve('awesome!')
      }, 3000);
    } catch (ex) {
      reject(ex);
    }  
  });
  return promise;
}

我已經確認executeStep2函數運行完成。 我的依據是我可以在控制台窗口中看到“步驟 2 已執行”。 然而,令我驚訝的是,我從未在控制台窗口中看到“全部完成”。 相反,我看到了上面提到的UnhandledPromiseRejectionWarning 關於這個結果,我不明白兩件事:

  1. 為什么我在控制台中沒有看到“全部完成”? executeStep2解決之后,該函數不應該被執行嗎?
  2. 拒絕來自哪里? 我沒有看到任何拒絕這一點的東西。

非常感謝您的幫助!

executeStep1()
    .then(result => executeStep2(param1, result, input))
    .then(result => { // no function(result) here
       console.log('All done');
       resolve(result);
    })
    .catch(err => reject(err))
  ;

當您調用使用 promise 的函數時會生成錯誤:

myButton.addEventListener('click', executeAction('0'));

您還需要在那里捕獲拒絕。

myButton.addEventListener('click', executeAction('0')
    .catch((error) => console.log('ERROR', error));

拒絕被捕獲在函數內部,但不在外部范圍內,因為executeAction('0')返回一個承諾,或者它會但您將其用作非異步函數,因此它創建一個承諾,然后返回一個掛起承諾無需等待解決。 這看起來像是導致拒絕的原因,並且由於上述原因也沒有處理。

這將修復它:

function executeAction(input) {      
  let param1 = 'A';
  return new Promise(function(resolve, reject) {
    try {
      executeStep1()
        .then(result => executeStep2(param1, result, input))
        .then(result => function(result) {
           console.log('All done');
           resolve(result);
        })
        .catch(err => reject(err))
      ;
    } catch (ex) {
      reject(ex);
    }
  });
}

您應該查看異步/等待。 它可以顯着清理此代碼。

 async function getSomething() { try { // throw 'Test error detected.' return 'test' } catch (e) { throw e } } async function testing() { try { const sample = await getSomething() return sample } catch (e) { throw e } } testing() .then((data) => console.log(data)) .catch((err) => console.log(err))

運行上面的示例,然后取消注釋 throw。 使用這種模式以獲得最大的勝利。 異常應該被拋出到函數被調用、顯示、使用、呈現等的表面級別。函數應該簡單地拋出錯誤。

這允許您使用錯誤處理中間件、高階函數、偵聽器、日志記錄等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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