Node.js:未处理的promise promise - UnhandledPromiseRejectionWarning

时间:2017-10-17 17:05:31

标签: javascript node.js promise

我有一个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. 拒绝来自何处?我没有看到任何拒绝这一点的内容。
  3. 非常感谢你的帮助!

2 个答案:

答案 0 :(得分: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 :(得分:0)

当您调用使用promises的函数时会生成错误:

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

你也需要在那里受到拒绝。

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

拒绝被捕获在函数内部,但不在外部作用域中,因为executeAction('0')返回一个promise,或者它会将它用作非异步函数,因此它创建一个promise然后返回等待承诺而不等待它被解决。这看起来像什么导致拒绝,并且由于上述原因也没有处理。

这将解决它:

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 / await。它可以显着清理此代码。

    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。使用此模式可获得最大胜利。应该将异常抛出到调用,显示,使用,渲染等函数的表面级别。函数应该简单地抛出错误。

这允许您使用错误处理中间件,高阶函数,侦听器,日志记录等