Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nesting node async.eachSeries

Been fighting with async module for half a day but can't get it to work properly when nesting few levels.

So this works ok:


    var async = require('async')

    var myarr = ["Outer - A", "Outer - B"];
    var myarr2 = ["Inner - A", "Inner - B"];
    var innerComplete = true;

    async.eachSeries(myarr, function( item, outerCallback) {
        console.log('Processing item ' + item);
        async.series([
            function(callback) {
                takeTime(2000, item, callback)
            },
            function(callback) {
                takeTime(1000, item, callback)
            },
            function(callback) {


                outerCallback();
            }
        ], function(err) {
            console.log("---OUTER SEQUENCE---")

        })
    }, function(err){
        console.log("---OUTER LOOP---")

    });

    function takeTime(ms, msg, callback) {
        console.log("Starting " + ms + " ms task from " + msg);
        setTimeout( function() { 
            console.log("Finished " + ms + " ms task from " + msg);
            callback();
        }, ms);
    } 

And it outputs everything nicely in sequence like this:

Processing item Outer - A
Starting 2000 ms task from Outer - A
Finished 2000 ms task from Outer - A
Starting 1000 ms task from Outer - A
Finished 1000 ms task from Outer - A
Processing item Outer - B
Starting 2000 ms task from Outer - B
Finished 2000 ms task from Outer - B
Starting 1000 ms task from Outer - B
Finished 1000 ms task from Outer - B
---OUTER LOOP---

But when I try to nest another eachSeries loop into it like this:


    var async = require('async')

    var myarr = ["Outer - A", "Outer - B"];
    var myarr2 = ["Inner - A", "Inner - B"];
    var innerComplete = true;

    async.eachSeries(myarr, function( item, outerCallback) {
        console.log('Processing item ' + item);
        async.series([
            function(callback) {
                takeTime(2000, item, callback)
            },
            function(callback) {
                takeTime(1000, item, callback)
            },
            function(callback) {
                async.eachSeries(myarr2, function( item2, outerCallback2) {
                    console.log('Processing item ' + item2);
                    async.series([
                        function(callback2) {
                            takeTime(2000, item2, callback2)
                        },
                        function(callback2) {
                            takeTime(1000, item2, callback2)
                        }
                    ], function(err) {
                        console.log('---INNER SEQUENCE---')

                    })
                }, function(err){
                    console.log("---INNER LOOP---")
                });

                outerCallback();
            }
        ], function(err) {
            console.log("---OUTER SEQUENCE---")

        })
    }, function(err){
        console.log("---OUTER LOOP---")

    });

    function takeTime(ms, msg, callback) {
        console.log("Starting " + ms + " ms task from " + msg);
        setTimeout( function() { 
            console.log("Finished " + ms + " ms task from " + msg);
            callback();
        }, ms);
    } 

It loses the execution order when entering the second eachSeries loop like this:

Processing item Outer - A
Starting 2000 ms task from Outer - A
Finished 2000 ms task from Outer - A
Starting 1000 ms task from Outer - A
Finished 1000 ms task from Outer - A
Processing item Inner - A
Starting 2000 ms task from Inner - A
Processing item Outer - B
Starting 2000 ms task from Outer - B
Finished 2000 ms task from Inner - A
Starting 1000 ms task from Inner - A
Finished 2000 ms task from Outer - B
Starting 1000 ms task from Outer - B
Finished 1000 ms task from Inner - A
---INNER SEQUENCE---
Finished 1000 ms task from Outer - B
Processing item Inner - A
Starting 2000 ms task from Inner - A
---OUTER LOOP---
Finished 2000 ms task from Inner - A
Starting 1000 ms task from Inner - A
Finished 1000 ms task from Inner - A
---INNER SEQUENCE---

I also tried out waterfall, mapSeries etc, but with same or otherwise messed up sequence of execution. Am I doing something wrong or doesn't the async module support such nesting?

like image 949
Timo Wallenius Avatar asked Sep 07 '14 17:09

Timo Wallenius


1 Answers

You're not calling the outerCallback2, you're not calling the callback, and you're calling the outerCallback immediately.

Fixed:

async.eachSeries(myarr, function( item, outerCallback) {
  ,----------------------------------------'
  |  console.log('Processing item ' + item);
  |  async.series([
  |      function(callback) {
  |                 `--------------,
  |          takeTime(2000, item, callback)
  |      },
  |      function(callback) {
  |                 `--------------,
  |          takeTime(1000, item, callback)
  |      },
  |      function(callback) {
  |     ,-----------'
  |     |     async.eachSeries(myarr2, function( item2, outerCallback2) {
  |     |    ,---------------------------------------------'
  |     |    |   console.log('Processing item ' + item2);
  |     |    |   async.series([
  |     |    |      function(callback2) {
  |     |    |          takeTime(2000, item2, callback2)
  |     |    |      },
  |     |    |      function(callback2) {
  |     |    |          takeTime(1000, item2, callback2)
  |     |    |      }
  |     |    |  ], function(err) {
  |     |    |      console.log('---INNER SEQUENCE---')
  |     |    `--->  outerCallback2(err); // <<<
  |     |       })
  |     |   }, function(err){
  |     |      console.log("---INNER LOOP---");
  |     `--->  callback(err); // <<<
  |         });
  |     }
  | ], function(err) {
  |      console.log("---OUTER SEQUENCE---")
  `--->  outerCallback(err); // <<<
    })
}, function(err){
    console.log("---OUTER LOOP---")
    console.log("everything done");
});
like image 119
Bergi Avatar answered Oct 22 '22 08:10

Bergi