2017-10-17 186 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))

运行此上述例子中,并取消抛出。使用这种模式获得最大的胜利。应该将异常抛出到函数被调用,显示,使用,渲染等的表面层次。函数应该简单地抛出错误。

这样就可以使用错误处理中间件,高阶函数,听众,记录等

相关问题