【问题标题】:Using bluebird Promises, how can I do a nested each?使用 bluebird Promises,我怎样才能做一个嵌套的每个?
【发布时间】:2015-02-19 01:05:09
【问题描述】:

我有 2 个数组,我想对它们的每个组合做一些事情。例如:

var array1, array2;

array1 = [1, 2, 3];

array2 = [4, 5, 5];

async.each(array1, function(val1, cb1) {
  return async.each(array2, function(val2, cb2) {
    return doProcessing(val1, val2, function(err) {
      return cb2(err);
    });
  }, function(err) {
    return cb(err);
  });
}, function(err) {
  return console.log('DONE');
});

如何使用 bluebird Promises 做到这一点?

我在这里使用async 模块,因为doProcessing 是一个异步调用。

【问题讨论】:

  • 更新为 JavaScript 而不是 CoffeeScript
  • 你使用的是什么版本的node/io?

标签: javascript asynchronous promise bluebird


【解决方案1】:

首先是关于doProcessing的承诺:

process = Promise.promisify(doProcessing);

如果你已经包含了 bluebird,那么在这种情况下使用回调是没有意义的。 现在它返回一个承诺,您可以轻松地使用它。至于问题的另一部分,您需要所有对 - 您可以将其重构为异步嵌套 for 循环:

return Promise.each(array1, function(val1){
     return Promise.each(array2, function(val2){
          return process(val1, val2);
     });
}).then(function(){
    // all done
});

请注意,如果数组仅包含数字,则执行正常循环而不是 promise - 如果值本身是从异步源获取的,则每个在这里都很有用。

或者 - 这里有一个更实用的 Ramda 方法:

var all = Promise.all.bind(Promise);
var wait = R.compose(all, R.map(all), R.xprod);
wait(arr1, arr2).map(R.apply(process));

【讨论】:

  • +1 用于 Ramda 方式,尽管我不确定它如何/是否有效。不需要all(R.map(all, R.map(R.map(process), R.xprod(arr1,arr2))))吗?
  • @Bergi Ramda 的禅意是一切都是默认柯里化的,数据最后传递。 wait 在这里所做的(稍微简化了一点)是创建一个函数,该函数首先获取叉积,然后将结果映射到 all 有效地等待每个数组。这个演讲非常适合为这种编程风格提供直觉youtube.com/watch?v=m3svKOdZijA
  • 哦,我已经有了直觉,但我说all需要在process之后执行
  • @Bergi [a1, a2] 中的 a1 来自 arr1 和 a2 来自 arr2 的值需要被解包它们被传递给process - 在 Ramda 中编写是正确的向左。请注意,wait 的返回结果是一个蓝鸟承诺——在其上调用.map 会隐式调用.all(这与array#map 不同,在这种情况下,您的评论会出现。
  • 这与功能较少的版本不同,它首先创建所有对,然后在它们上执行process。在所有对上也是公平的并发(可以是.each 是连续的)。
猜你喜欢
  • 2019-09-01
  • 1970-01-01
  • 2011-09-03
  • 2021-04-13
  • 2021-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-03
相关资源
最近更新 更多