2014-09-07 9 views
5

State combattendo con il modulo asincrono per mezza giornata ma non riescono a farlo funzionare correttamente quando si annidano pochi livelli. Un po 'di un lungo post a causa del codice, ma per favore nuda con me, tutto il codice dovrebbe funzionare ok.Nodo di annidamento async.eachSeries

Quindi questo funziona bene:

 

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

Ed emette tutto bene in sequenza come questa:

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

Ma quando provo a nidificare un altro ciclo eachSeries in questo modo:

 

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

Perde l'ordine di esecuzione quando si immette il secondo ciclo eachSeries in questo modo:

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

Ho anche provato waterfall, mapSeries ecc., Ma con sequenza di esecuzione uguale o altrimenti incasinata. Sto facendo qualcosa di sbagliato o il modulo asincrono non supporta tale nidificazione?

risposta

10

Non chiami lo outerCallback2, non chiami lo callback e chiami immediatamente lo outerCallback.

fisso:

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"); 
}); 
+0

meraviglie lavorato e un pezzo eccellente per comprendere meglio il callback in una struttura annidata come questo. Milioni di grazie Bergi! –

+0

Grazie mille che è stato utile, c'è un modo più "basato sulla chiamata di funzioni" per farlo? – timhc22

+0

@ timhc22: Cosa intendi per "funzione chiamata basata"? Se non ti piace passare i callback in giro e preoccuparti dei valori di ritorno, dovresti dare un'occhiata alle promesse. – Bergi

Problemi correlati