简体   繁体   English

两个嵌套的async.each调用

[英]Two nested async.each calls

I have the following method: 我有以下方法:

mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {
    var result = [];
    async.each(a, function(itemA, cb1) {
        async.each(b, function(itemB, cb2) {
            if (itemA[attr1] == itemB[attr1]) {
              itemB[attr2] = val;
            }
            result.push(itemB);
            cb2(null, result);
          },
          function(e, result) {
            sails.log('[result]', result);
            cb1(e, result);
          });
      },
      function(e, result) {
        cb(e, result);
      });
  }

I basically want to compare an array of objects (A) to another array of objects (B), and return an updated array (C) with every item in B, but updates with attributes from A. 我基本上想将一个对象数组(A)与另一个对象数组(B)进行比较,并与B中的每个项目返回一个更新后的数组(C),但是使用A中的属性进行更新。

The above [result] returns undefined. 上面的[结果]返回未定义。

Thanks 谢谢

First of all, this is all synchronous code, so you don't need async module, you just need regular looping constructs. 首先,这都是同步代码,因此您不需要异步模块,只需要常规的循环结构即可。 But let's assume you need async. 但是,假设您需要异步处理。

Use async.map instead of async.each , for more brevity: 使用async.map而不是async.each可以更简洁:

mergeAinBbyAttr: function(a, b, attr1, attr2, val, cb) {

    async.map(a, function(itemA, cb) {
        async.map(b, function(itemB, cb) {
            if (itemA[attr1] === itemB[attr1]) {
              itemB[attr2] = val;
            }
            cb(null, itemB);

          },cb);

      },cb);
  }

you do not need to name the cb variables different names, because they have different scopes. 您无需为cb变量命名不同的名称,因为它们具有不同的作用域。

If you want a flattened array at the end of this routine, I would recommend using _.flatten or _.flattenDeep from lodash or underscore. 如果要在此例程的末尾使用扁平化数组,则建议使用lodash或下划线中的_.flatten_.flattenDeep

Note that this: 注意:

function(e, result) {
   cb(e, result);
});

can just be reduced to: 可以简化为:

cb

================================= ================================

Doing this with synchronous methods: 使用同步方法执行此操作:

    mergeByAttr: function(a, b, attr1, attr2, val) {

      return a.map(function(itemA){
          return b.map(function(itemB){
                if (itemA[attr1] === itemB[attr1]) {
                  itemB[attr2] = val;
                }
                return itemB;
           });

      });
   }

As you can see, either way, you will get nested arrays, it has nothing to do with the async module, but the nature of your code. 如您所见,无论哪种方式,您都将获得嵌套数组,它与async模块无关,但与代码的性质无关。

The more performant, but less functional way: 性能更高但功能较少的方式:

     mergeByAttr: function(a, b, attr1, attr2, val) {

          a.forEach(function(itemA){
              b.forEach(function(itemB){
                    if (itemA[attr1] === itemB[attr1]) {
                      itemB[attr2] = val;
                    }
                    return itemB;
               });

          });
       }

Well I watched That the answer above help you, only I want highlight one thing about your error: 好吧,我看着上面的答案对您有所帮助,只有我想强调一下有关您的错误的一件事:

[result] returns undefined. [结果]返回未定义。

is because according to documentation, the optional function only has 1 parameter, and you are trying to get 2 parameter: function(e, result) 因为根据文档,可选函数只有1个参数,而您试图获取2个参数:function(e,result)

http://caolan.github.io/async/docs.html#each http://caolan.github.io/async/docs.html#each

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM