async.js each get index in iterator

后端 未结 6 1693
一整个雨季
一整个雨季 2021-02-02 07:04

I\'m using caolan\'s async.js library, specifically the .each method.

How do you get access to the index in the iterator?

async.each(ary, function(elemen         


        
6条回答
  •  旧时难觅i
    2021-02-02 07:53

    The method async.each() will iterate the array in parallel, and it doesn't provide the element's index to the iterating callback.

    So when you have:

    function( done ){
    
      async.each(
    
        someArray,
    
        function( item, cb ){
          // ... processing
    
          cb( null );
        },
    
        function( err ){
          if( err ) return done( err );
    
          // ...
          done( null );
        }
      );
    }
    

    While you COULD use Array.indexOf() to find it:

    function( done ){
    
      async.each(
    
        someArray,
    
        function( item, cb ){
          // ... processing
    
          var index = someArray.indexOf( item );
    
          cb( null );
        },
    
        function( err ){
          if( err ) return done( err );
    
          // ...
          done( null );
        }
      );
    }
    

    This requires an in-memory search in the array for EVERY iteration of the array. For large-ish arrays, this might slow everything down quite badly.

    A better workaround could be by using async.eachSeries() instead, and keep track of the index yourself:

    function( done ){
    
      var index = -1;
      async.eachSeries(
    
        someArray,
    
        function( item, cb ){
    
          // index is updated. Its first value will be `0` as expected
          index++;
    
          // ... processing
    
          cb( null );
        },
    
        function( err ){
          if( err ) return done( err );
    
          // ...
          done( null );
        }
      );
    }
    

    With eachSeries(), you are guaranteed that things will be done in the right order.

    Another workaround, which is the async's maintainer's first choice, is to iterate with Object.keys:

    function( done ){
    
      async.each(
    
        Object.keys( someArray ),
    
        function( key, cb ){
    
          // Get the value from the key          
          var item = someArray[ key ];
    
          // ... processing
    
          cb( null );
        },
    
        function( err ){
          if( err ) return done( err );
    
          // ...
          done( null );
        }
      );
    }
    

    I hope this helps.

提交回复
热议问题