Javascript承诺,为什么拒绝是未处理的?

Javascript承诺,为什么拒绝是未处理的?,javascript,es6-promise,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.$':

我有以下代码:

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

如果任何条件语句失败,我将在以下位置获得
错误:未处理的拒绝:Promise Promise{'voteDenied'}原因:voteDenied
。为什么这件事没有被抓住?或者这是一种错误的处理方式,用一个假值或其他东西进行解析并在then()函数中处理结果会更好吗?

在我看来,代码中最有趣的部分并没有显示出来,而是替换为

从错误消息中可以看出,
validateRole
返回
Promise
,您正在示例代码的最后一行处理它。如果您的
validateRole().then()
不包含承诺拒绝的处理程序(从您的示例中看不到),那么这个错误很明显-您没有处理承诺拒绝


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

在我看来,代码中最有趣的部分没有显示出来,而是替换为示例中的

从错误消息中可以看出,
validateRole
返回
Promise
,您正在示例代码的最后一行处理它。如果您的
validateRole().then()
不包含承诺拒绝的处理程序(从您的示例中看不到),那么这个错误很明显-您没有处理承诺拒绝


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

因为您
},所以拒绝。
返回的承诺。由于
reject
返回未定义的值,因此无法执行
.catch

+不要使用承诺构造函数反模式

让我们稍微清理一下,然后您可以随意添加日志记录

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`
}

因为您
},所以拒绝。
返回的承诺。由于
reject
返回未定义的值,因此无法执行
.catch

+不要使用承诺构造函数反模式

让我们稍微清理一下,然后您可以随意添加日志记录

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`
}

有点旁白:既然
游戏。findOne
已经返回了一个承诺,那么做出一个
新承诺来包装它又有什么意义呢?你的新承诺做了什么,而来自
游戏.findOne
的承诺做不到?因此,如果需要,我可以使用resolve('custom response'),并在.then()中使用。你的意思是你想在
then
之外使用
resolve
?否则,如果您只计划在
then
内部调用
resolve
,则可以
返回
,因为前面的
then
的返回值作为参数提供给后面的
then
。也就是说,
return Game.findOne(…).then(function(){return“custom response”}).catch(…)
将向外部
验证程序(…)提供
自定义响应函数。有点像旁白:既然
游戏。findOne
已经返回了一个承诺,那么做出
新承诺来包装它有什么意义?你的新承诺做了什么,而来自
游戏.findOne
的承诺做不到?因此,如果需要,我可以使用resolve('custom response'),并在.then()中使用。你的意思是你想在
then
之外使用
resolve
?否则,如果您只计划在
then
内部调用
resolve
,则可以
返回
,因为前面的
then
的返回值作为参数提供给后面的
then
。也就是说,
return Game.findOne(…).then(function(){return“custom response”}).catch(…)
将向外部
验证程序(…)提供
自定义响应函数。我假设所示代码中的catch将。。。捕获并处理所示代码中的任何拒绝。您正在捕获承诺中的错误,但生成对
validateRole
返回的承诺的拒绝。当然,乍一看并不是那么明显:)我假设所示代码中的catch会。。。捕获并处理所示代码中的任何拒绝。您正在捕获承诺中的错误,但生成对
validateRole
返回的承诺的拒绝。当然,乍一看就不那么明显:)@Trax,扩展了答案,因为我不知道您是否打算将
findOne()
中的错误处理为
'playerNotFound'
。所以我添加了一个处理它们的版本seperately@Trax,扩展了答案,因为我不知道您是否打算将
findOne()
中的错误处理为
'playerNotFound'
。因此,我添加了一个版本,分别处理它们