2014-07-26 8 views
5

Ho una coda asincrona che sto spingendo a cui farò qualcosa. Il modo in cui generi gli elementi che ho bisogno di inserire è attraverso alcune liste annidate da un oggetto dati. La coda finisce per elaborare tutto ma, per qualche motivo, non riesco ad accedere alla mia callback principale con lo console.log('All done.'). Ho rimosso la maggior parte delle cose inutili e ho lasciato solo cose asincrone. Che cosa sto facendo di sbagliato? Mi sto perdendo qualcosa?Ciclo asincrono annidato che spinge verso una coda asincrona che non chiama il callback principale

var q = async.queue(function(task, callback) { 
    console.log('hello ' + task); 
    callback(); 
}, 2); 

function A(data) { 
    B(data, function() { 
    // THIS ISN'T getting called. 
    console.log('All done.'); 
    }) 
} 

function B(data, callback1) { 
    var list = [[1,2], [3,4], [5,6]]; 
    async.each(list, function(item, callback1) { 
    async.each(item, function(i, callback2) { 
     doWork(i, function() { 
     console.log('Work done'); 
     }) 
     callback2(); 
    }, 
    // THIS should be called when everything in this each is done. 
    callback1) 
    }) 
} 

function doWork(i, callback3) { 
    q.push(i, callback3); 
} 
+0

Per chiarire la domanda: quale risultato ottieni? Cosa ti aspettavi? Dov'è il codice che chiama A e B? – hugomg

+0

Tutte le attività "ciao" + e "Lavoro fatto" vengono stampate. Ma solo il principale "Tutto fatto". non lo è. – owenlero

+0

per favore correggi il tuo codice così almeno è sintatticamente corretto, altrimenti è davvero difficile capirlo – soulcheck

risposta

1

Ecco il codice con alcuni commenti, come parlando di callback di callback è un po 'complicato:

function B(data, callback1 //this is what you want to be called) { 
    var list = [[1,2], [3,4], [5,6]]; 

    //async1 
    async.each(list, function(item, callback1 //now callback1 is a function passed to your code by `async.each` not the original callback1) { 
     //async2 
     async.each(item, function(i, callback2) { 
     doWork(i, function() { 
     console.log('Work done'); 
     }) 
     callback2(); 
    }, 
    // THIS is actually called, it's just a different function than you think it is 
    callback1) 
    }) 
} 

Il problema è che si è utilizzato lo stesso nome sia per l'argomento della B e callback argomento della funzione di callback async1.

Così il callback1 Async1 all'interno callback nasconde l'esterno callback1 ed è in realtà la richiamata Async1 interno che serve per passare il controllo al async.each.

soluzione è semplice: rinominare il parametro di callback Async1, ad esempio:

function B(data, callback1) { 
    var list = [[1,2], [3,4], [5,6]]; 
    async.each(list, function(item, async1_callback) { //here lies the rename 
    async.each(item, function(i, callback2) { 
     doWork(i, function() { 
     console.log('Work done'); 
     }) 
     callback2(); 
    }, 
    // this is now called as expected 
    callback1 
    ); 
    // BUT we forgot to call the async1_callback, so let's do it: 
    async1_callback(); 

}; 

funziona come previsto.

+0

Grazie, non posso credere di averlo perso ... Ma l'altro problema è che sta uscendo con "Tutto fatto" prima - dovrebbe uscire per ultimo quando il ciclo è fatto bene? Mi manca qualcos'altro? – owenlero

+0

Manca ancora una chiamata a async1_callback() - controlla l'aggiornamento. Per quanto riguarda "All done" in corso di stampa - probabilmente perché né async.each né le operazioni in coda chiamano process.nextTick ovunque e il codice non cede al ciclo degli eventi. Per quanto riguarda la stampa solo una volta, aggiungilo come callback finale a async1, non async2 – soulcheck

Problemi correlati