Javascript承诺,为什么拒绝unhandeled?

时间:2017-10-29 12:06:53

标签: javascript es6-promise

我有以下代码:

function validateRole(message, cmdCalled) {
  return new Promise(function(resolve, reject) {
    winston.debug('Checking user\'s role');
    Game.findOne({
      running: true,
      'players.id': message.author.id
    }, {
      'players.$': 1
    }).then(function(result) {
      console.log(result);
      if (!result) reject('playerNotFound');
      if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) {
        message.author.send('Wolves are not allowed to vote!');
        reject('voteDenied');
      }
    }, reject).catch(function(err) {
      winston.debug(err);
    });
  });
}
validateRole(message,'someCommand').then(...)

如果任何条件语句失败,我会得到error: Unhandled Rejection at: Promise Promise { <rejected> 'voteDenied' } reason: voteDenied。为什么这不被抓住?或者这是处理事情的错误方法,用虚假值或其他东西解决并在then()函数中处理结果会更好吗?

2 个答案:

答案 0 :(得分:2)

因为您}, reject).返回了承诺。并且由于reject返回未定义,因此.catch无法执行。

+不要使用Promise-constructor反模式。

让我们稍微清理一下,然后在任何地方添加日志记录。

function validateRole(message, cmdCalled) {
  return Game.findOne({
    running: true,
    'players.id': message.author.id
  }, {
    'players.$': 1
  })
  .catch(function(err){
    console.log("error", err);
    //implicitely returns undefined as the `result` into the following `.then()`
  })
  .then(function(result) {
    if (!result) 
      throw 'playerNotFound';

    if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) {
      message.author.send('Wolves are not allowed to vote!');
      throw 'voteDenied';
    }
  });
  //and after this you either have a promise with a valid result,
  //or a rejected promise containing 'playerNotFound' or `voteDenied`
}

或者如果您想单独处理请求错误

function validateRole(message, cmdCalled) {
  return Game.findOne({
    running: true,
    'players.id': message.author.id
  }, {
    'players.$': 1
  })
  .then(function(result) {
    if (!result) 
      throw 'playerNotFound';

    if (cmdCalled === 'vote' && result.players[0].role.match(/wolf/gi)) {
      message.author.send('Wolves are not allowed to vote!');
      throw 'voteDenied';
    }
  }, function(err){
    //this will catch Errors from `findOne()` but not the errors thrown in the function above
    console.log(err);
    throw 'requestFailed';
  });
  //and after this you either have a promise with a valid result,
  //or a rejected promise containing 'playerNotFound' or `voteDenied` or `requestFailed`
}

答案 1 :(得分:0)

在我看来,代码中最有趣的部分未显示,并在示例中替换为...

从错误消息中可以看出validateRole返回Promise并且您在示例代码的最后一行处理了它。如果您的validateRole().then()不包含拒绝承诺的处理程序(并且无法从您的示例中看到),则此错误很明显 - 您不会处理承诺拒绝。

因此,请检查您是否拥有承诺拒绝的处理程序到您的示例的隐藏部分或显示您在这里有什么。