2017-10-17 209 views
-1

我有一個Node.js應用程序。這個應用程序有一個按鈕,啓動一個進程。該過程中的步驟將返回承諾。我試圖將這些承諾鏈接在一起。出於某種原因,我收到了UnhandledPromiseRejectionWarning。但是,在我看來,我已經正確設置了這一點。我的代碼如下所示:Node.js:未處理的承諾拒絕 - 未處理的拒絕拒絕警告

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. 拒收來自哪裏?我沒有看到任何拒絕這個的東西。

非常感謝您的幫助!從當你調用使用承諾的功能(S)產生

+0

刪除'函數(結果)'中第二個'then'。您已經在那裏使用箭頭函數語法來聲明該函數。 –

+0

無論如何避免['Promise' constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)!順便說一句,你從來不需要'在新的Promise'回調中嘗試{...} catch(err){reject(err)}',構造函數會自動執行該操作。 – Bergi

+0

你的'executeStep2'中的'[something]'究竟是一個實際上可能拋出異常的表達式? – Bergi

回答

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

這是更接近。我運行它時不再掛起。但是,我仍然收到'UnhandledPromiseRejectionWarning'錯誤。 –

0

錯誤:

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))

運行此上述例子中,並取消拋出。使用這種模式獲得最大的勝利。應該將異常拋出到函數被調用,顯示,使用,渲染等的表面層次。函數應該簡單地拋出錯誤。

這樣就可以使用錯誤處理中間件,高階函數,聽衆,記錄等

相關問題