简体   繁体   中英

node.js async.series with async.each not doing as expected

I'm really struggling to get arrays iterated in a certain order and each one should finish before the next can start. I've tried using async.series and async.each but the results are not as I expected them.

I have this code:

var async = require('async');
var abc = ['a', 'b', 'c'];

// Step 1
function one(callback) {
  async.each(abc, function(issue, callback) {
    setTimeout(function(){
      issue += '1';
      console.log('Processing issue ' + issue);
    }, 2000);

    callback();
  }, function(err) {
    if(err) {
      console.log('Fail 1');
    } else {
      console.log('Success 1');
    }
  });
}

// Step 2
function two(callback) {
  async.each(abc, function(issue, callback) {
    setTimeout(function(){
      issue += '2';
      // Perform operation on file here.
      console.log('Processing issue ' + issue);
    }, 2000);

    callback();
  }, function(err) {
    if(err) {
      console.log('Fail 2');
    } else {
      console.log('Success 2');
    }
  });
}

// Step 3
function three(callback) {
  async.each(abc, function(issue, callback) {
    setTimeout(function(){
      issue += '3';
      // Perform operation on file here.
      console.log('Processing issue ' + issue);
    }, 2000);

    callback();
  }, function(err) {
    if(err) {
      console.log('Fail 3');
    } else {
      console.log('Success 3');
    }
  });
}

async.series([
  function(callback) {
    console.log('step 1 in async.series');
    one(callback);

    callback();
  },
  function(callback) {
    console.log('step 2 in async.series');
    two(callback);

    callback();
  },
  function(callback) {
    console.log('step 3 in async.series');
    three(callback);

    callback();
  }
], function(err) {
  if(err) return next(err);

  console.log('Done:');
});

Result:

step 1 in async.series
Success 1
step 2 in async.series
Success 2
step 3 in async.series
Success 3
Done:
//After two second timeout all below happens at once
Processing issue a1
Processing issue b1
Processing issue c1
Processing issue a2
Processing issue b2
Processing issue c2
Processing issue a3
Processing issue b3
Processing issue c3

Expected:

step 1 in async.series
//Expected below after two second timeout
Processing issue a1
Processing issue a2
Processing issue a3
Success 1
step 2 in async.series
//Expected below after two+two second timeout
Processing issue b1
Processing issue b2
Processing issue b3
Success 2
step 3 in async.series
//Expected below after two+two+two second timeout
Processing issue c1
Processing issue c2
Processing issue c3
Success 3
Done:

What should I do instead to get expected results??

Thanks!

async.each happens in parallel, so all of these function get ran at the same time. You are looking for the async.eachSeries method: https://www.npmjs.com/package/async#eachseries-arr-iterator-callback

The same as each, only iterator is applied to each item in arr in series. The next iterator is only called once the current one has completed. This means the iterator functions will complete in order.

Put all of those callback()s inside the setTimeout()s. Then everything should work as you'd expect.

Edit: Each step should look similar to this:

// Step 1
function one(done) {
  console.log('step 1 in async.series');
  async.each(abc, function(issue, callback) {
    setTimeout(function(){
      issue += '1';
      console.log('Processing issue ' + issue);
      callback();
    }, 2000);
  }, done);
}

And the actual series should look like this:

async.series([one, two, three], function(err, data){
  if (err !== null) {
    console.log(data);
  } else {
    console.error(err);
  }
});

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