【问题标题】:Un-handled rejection from promise.each来自 promise.each 的未处理拒绝
【发布时间】:2017-10-03 16:09:41
【问题描述】:

我正在尝试使用 bluebird 的 Promise.each() 进行多个数据库查询。我被卡住的部分是我无法处理所有的拒绝(如果多个承诺失败)。如果我使用 Promise.all() 做同样的事情,它可以正常工作(它会!因为在 Promise.all() 中,如果 1 个承诺失败,结果也会被拒绝)。我的问题是: 我应该如何处理 Promise.each() 中的拒绝?

function foo(bar){
  return new Promise(resolve, reject){
  var query = "elect count(*) from students Where 1=1";//DELIBRATE MISTAKE
  connection.query(query, function(err, result){
    if(err){reject(err)}resolve(result);
  })
 }
}
function api(req, res){
  var tasks = [];
  for(var i = 0; i < 10; i++){
     tasks.push(foo(bar));
  }
  Promise.each(tasks).catch(err=>{return err;});
  res.send('message')
}    

回应: Unhandled rejection Error: ER_PARSE_ERROR

【问题讨论】:

  • 我能想到的是对于第一次拒绝,catch 会处理拒绝并返回错误。但是对于随后的拒绝,没有人能抓住它们。
  • foo 不返回承诺。 rejectresolve 是在哪里定义的?
  • @alexmac 错误,已更正。只是在这里写了一个例子。
  • 您的意思是Promise.all(接受一系列承诺)而不是Promises.each
  • 我想要的只是一个系列 Promise.all

标签: javascript node.js promise bluebird


【解决方案1】:

您错误地使用了Bluebird#each 方法。此方法执行以下操作:

迭代一个数组,或者一个数组的promise,它包含promise(或promise和values的混合),给定的迭代器函数带有签名(value, index, length),其中value是a的解析值输入数组中的相应承诺。

所以第一个参数必须是一个 promises/values 数组,第二个是一个回调,它接受三个参数:value, index, length

工作示例:

let queryAsync = Promise.promisify(connection.query, { context: connection });

function foo(bar) {
  var query = 'elect count(*) from students Where 1=1'; // DELIBRATE MISTAKE
  return queryAsync(query);
}

function api(req, res){
  var tasks = [/* TODO: fill array with taskIds or something else*/];

  Promise
    .each(tasks, task => foo(task))
    .then(() => res.send('message'))
    .catch(err => {
      console.log(err);
      res.status(500).send(err);
    });
}

在上面的例子中,我使用Bluebird#promisify 方法来promisify 回调风格的connection.query 函数。 Bluebird 已经提供了 promisification 功能,您不应该创建自己的。

【讨论】:

  • Use Bluebird#promisify to promisify callback-style connection.query function. 这将有何帮助?这有何不同?如果我已经从函数 foo(bar) 返回了一个承诺。另外,我已经修改了这个例子,只是在这里显示它无法处理拒绝,所以如果我只使用 catch 和 promise.each() 会不会有问题?
  • 这只是建议,不正确使用Bluebird#each方法的真正问题,我提到过。 Bluebird#promisify 呢,你已经在使用 Bluebird 模块,为什么要创建自行车(我的意思是使用 Promise 构造函数),而这个库已经具有所需的功能?
  • where value is the resolved value of a respective promise in the input array. 但这里 tasks 不是一系列承诺,task 也不是
  • 这不是关于Bluebird#each 方法中的第一个参数 - promise 和值的数组,而是关于第二个参数 - callback。这个回调应该返回一个 promise,并且你的 foo 函数会返回它。
猜你喜欢
  • 2019-08-07
  • 2021-03-27
  • 2019-03-15
  • 2016-07-21
  • 2021-12-30
  • 1970-01-01
  • 2017-09-27
  • 2019-03-14
  • 2019-04-16
相关资源
最近更新 更多