简体   繁体   中英

trouble with Async.js for Node.JS

im trying to fight against the callback hell but im having trouble with my code.

Someone knows how to implement async.js to a structure like this:

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){

   });

  }
 }
}

UPDATE:

i will put here the real structure i need to implement

     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);
          }

In common your code will looks like this:

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

To good readability you have to not write it as is.
Instead you are define some functions, which modify items and calls next callbacks.
This functions called as iterators .

For example:

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

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

Also, we can to generate iterators depends our needs:

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]
});

For apply multidimensional structures we can to call async methods from our iterators:

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

With updated question. Here we just build our iterator and then run :)

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

  ]
  */

}

May be need to play with limits here...
But concept of build this should be clear now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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