【问题标题】:trouble with Async.js for Node.JSNode.JS 的 Async.js 出现问题
【发布时间】:2016-02-18 04:25:54
【问题描述】:

我试图与回调地狱作斗争,但我的代码有问题。

有人知道如何将 async.js 实现为这样的结构:

for(var i=0;i<array1.length;i++){
 //do something
 for(var j=0;j<array2.length;j++){
  //do something
  for(var k=0;k<array3.length;k++){
   //do something
   bd.findSomethig(array3[k].id, function(err, result){

   });

   bd.findSomethig(array3[k].ref, function(err, result){

   });

  }
 }
}

更新:

我将把我需要实现的真实结构放在这里

     var array1 = array;
      var rsp=[];
        for(var i=0;i<array1.length;i++){
          var object1 = new Object();

          object1.a="xx";
          object1.b="xx";
          object1.c="xx";
          object1.d="xx";

            var array2=array1[i].array2;

            var array2Result=[];
            for(var j=0;j<array2.length;j++){

              var object2 = new Object();

                object2.a="xx";
                object2.b="xx";
                object2.c="xx";
                object2.d="xx";

              var array3=array1[i].array2[j].array3;
              var array3Result=[];

              for(var k=0;k<array3.length;k++){

               var object3 = new Object();
               var array4=array1[i].array2[j].array3[l].array4;
                var array3Result4=[];

                for(var l=0;l<array4.length;l++){

                  var object4 = new Object();
                  var array5=array1[i].array2[j].array3[k].array4[l].array5;

                  for (var m=0;m<array5.length;m++){
                    if(someConditional){

                        object4.a="xx";
                        object4.b="xx";
                        object4.c="xx";
                        object4.d="xx";

                        //Here i need to call a BD function to find some rows i need to build the JSON response
                          bd.findSomethig(array5[m].id, function(err, result){
                              object4.e=result;
                           });

                           bd.findSomethig(array5[m].ref, function(err, result){
                              object4.f=result;
                           });

                        array3Result4.push(object4);
                    }

                  }
                object3.a=segments;
                array3Result.push(object3);
              }
                object2.e=array3Result;
              array2Result.push(object2)              
            }
            object1.e=array2Result;
            rsp.push(object1);
          }

【问题讨论】:

  • 只删除两个外循环。
  • 所有循环都很重要。因为我每次都需要迭代
  • 它们是三个不同的数组 :( 需要更改答案...
  • 是的,我更新了要求以更清晰。因为在原始帖子中,您可能认为是不同的数组
  • 就像嵌套循环一样嵌套async.each/async.map(或…series,或任何你需要的)。有什么问题?

标签: javascript node.js callback async.js


【解决方案1】:

您的代码通常如下所示:

async.map(array1, function(item, next){
   var modifiedItem = modify(item);
   next(null, modifiedItem);
}, function(err, results){
   // results is an array of modifiedItem's here
});

为了具有良好的可读性,您不必按原样编写它。
相反,您定义了一些函数,它们修改项目并调用 next 回调。
这个函数称为iterators

例如:

function doubleIterator(item, next) {
  next(null, 2*item);
}

async.map([1,2,3], doubleIterator, function (err, results) {
  // we have results = [2, 4, 6] here
});

此外,我们可以根据需要生成迭代器:

function getFieldIterator(field) {
   return function (item, next) {
      next(null, item[field]);
   }      
}
async.map([{id: 1}, {id: 7}], getFieldIterator('id'), function(err, results){
  // results = [1, 7]
});

为了应用多维结构,我们可以从我们的迭代器中调用async 方法:

   function getMapIt(iterator) {
     return function(item, next) {
       async.map(item, iterator, next);
     };
   }


async.map([[1, 2], [3, 4]], getMapIt(doubleIterator), function(err, results){
  // getMapIt returns iterator which receive two arrays
  // it run async.map on each of them
  // and apply doubleIterator in each
  // so, we have results = [[2, 4], [6, 8]] here
})

有更新的问题。 这里我们只是构建我们的迭代器然后运行:)

async.map(array1, mapIterator(mapIterator(searchIterator)), callback);
// assume you have just 3-dimensional array
function mapIterator(iterator) {
  return function(item, next) {
    async.map(item, iterator, next);  
  }
}

//with structure in your question:
function mapField(field, iterator) {
  return function(item, next) {
    async.map(item[field], iterator, next);  
  }
}
// and use it as
// mapField('array2', mapField('array3', searchIterator))

function searchIterator(item, next) {
   async.parallel({
     id: search(item.id),
     ref: search(item.ref)
   }, next);       
}
function search(id) {
  return function(next){
    bd.findSomethig(id, next);
  }
}
function callback(err, results) {
  if (err) return console.error(err);
  console.log('Batch of results: ',results);
  // It should be represented same of array1 structure:
  /*
  [
    [
       [{id: dbRes, ref: dbRes}, {id: dbRes, ref: dbRes}],
       [{id: dbRes, ref: dbRes}, {id: dbRes, ref: dbRes}],
       [{id: dbRes, ref: dbRes}, {id: dbRes, ref: dbRes}]
    ],
    [
       [{id: dbRes, ref: dbRes}, {id: dbRes, ref: dbRes}],
       [{id: dbRes, ref: dbRes}, {id: dbRes, ref: dbRes}]
    ]

  ]
  */

}

可能需要在这里玩限制...
但是现在构建这个的概念应该很清楚了。

【讨论】:

  • 仍然不知道如何实现.. 我需要迭代 5 个数组并构建一个 JSON 以返回给客户端,在最后一个数组中我需要对 BD 进行查询,结果将是要返回的 JSON 中的值。我尝试将“async.each”嵌套 5 次,但我认为不推荐
  • each 只是一个循环。如果你想用你的数据构建结果,你需要一个map。什么是 5 个数组? array1[i1][i2][i3][i4][i5] = {id: 1, ref: 3}?如果是,不仅仅是构建更长的迭代器:mI(mI(mI(mI(searchIterator)))) 对于这种情况,您可能需要编写嵌套迭代器构建器。
  • 这不是为您工作而提供的服务。在我的代码示例中您究竟无法理解什么?关注minimal reproducible example
  • 我看不到您如何迭代数组并从每个数组中恢复 te 信息以推入新数组。
  • 我在回答开始时添加了一些解释
猜你喜欢
  • 2015-06-09
  • 2014-04-26
  • 1970-01-01
  • 2013-06-20
  • 1970-01-01
  • 2013-10-28
  • 2018-08-24
  • 2016-02-26
  • 2015-07-06
相关资源
最近更新 更多