2014-05-20 8 views
7

Ho una funzione asincrona che funziona con il risultato di altre due funzioni asincrone.Come gestire una funzione asincrona che dipende da più altre funzioni asincrone

Fino ad ora quello che stavo facendo è che scrivo function2 nel function1 callback e function2 nel callback di function2

function1(callbackFunction() { 
    function2(callbackFunction() { 
     function3() 
    }) 
}) 

C'è un altro modo per gestire questa situazione. Lavoro solitamente con codice JavaScript nel lato client e in nodeJs.

Il mio scenario è che per function2 non ho bisogno di output da function1. In altre parole, function1 e function2 sono indipendenti; ma la funzione 3 dipende da function1 e function2.

Voglio che la mia funzione2 funzioni indipendentemente su function1 ma function3 per funzionare in base a functio1 e function2.

C'è qualcosa di simile

function1(); 
function2(); 
when(funtion1.complete && funtion2.complete) { 
    function3(); 
} 
+1

Hai avuto l'idea giusta. Se ti stanchi di sempre più nidificazione, dai un'occhiata alla libreria async.js in npm. Quello che hai è gestito dall'assistente "serie" in async.js https://github.com/caolan/async#seriestasks-callback – Paul

+0

@Paul Ho apportato alcune modifiche alla domanda, potresti considerare anche questo. – Okky

+1

Sembra che Jacob ti abbia già scritto un'ottima risposta ...! – Paul

risposta

6

Ci sono alcune buone biblioteche per affrontare orchestrare funzioni asincrone. async e q (o altre librerie Promises/A).

Se function2 non dipende dal risultato di function1, è possibile eseguirli in parallelo. Ecco come appare usando async (questi esempi presuppongono che il callback ha una firma function(err, result), che è il modello de facto per Node:

async.parallel([ 
    function(callback) { function1(callback); }, 
    function(callback) { function2(callback); } 
], function(err, values) { 
    function3(values[0], values[1]); 
}); 

Se function2 dipende dal risultato da function1, waterfall può essere un modello migliore:

async.waterfall([ 
    function(callback) { function1(callback); }, 
    function(result, callback) { function2(result, callback); }, 
    function(result, callback) { function3(result, callback); }, 
]); 

Personalmente, mi piace q, perché si può passare promesse in giro e fare tutti i tipi di cose carine Ecco come questa apparirebbe usando che:.

q.nfcall(function1) 
    .then(function(result) { return q.nfcall(function2); }) 
    .then(function(result) { return q.nfcall(function3); }) 
    .fail(function(err) { 
     // If any of them fail, this is called. 
    }); 

O se function1 e function2 può essere fatto in modo arbitrario:

q.all([q.nfcall(function1), q.nfcall(function2)]) 
.then(function(values) { function3(values[0], values[1]); }) 
.fail(function(err) { 
}); 
+0

e come passare i risultati alla funzione 2? –

2

Ecco una soluzione che ho cotto. Si può provare un gestore di chiamata per chiamare le funzioni dipendenti

var func1 = function() { 
    console.log("Dependant call ... " + 1); 
}; 
var func2 = function() { 
    console.log("Dependant call ... " + 2); 
}; 
var func3 = function() { 
    console.log("Dependant call ... " + 3); 
}; 
var func4 = function() { 
    console.log("Dependant call ... " + 4); 
}; 


var CallManager = function(funcs_config) { 
    var _this = this; 

    _this.functions = funcs_config; 
    _this.callAsynchronous = function(f) { 
     if (f != undefined) { 
      for (var i = 0; i < f.length; i++) { 
       f[i].call(function() { 
        this.callAsynchronous(f.splice(0,1)); 
       }); 
      } 
      return; 
     } 

     for (var func in _this.functions) { 
      if (_this.functions[func].length == 0) { 
       //not dependent to any function 
      } else { 
       console.log('Calling....' + func); 
       _this.callAsynchronous(_this.functions[func]); 
       eval(func +'();'); 
      } 
     } 
    }; 

    return _this; 
}; 


var callManager = new CallManager({ 
    //dependency configuration 
    func2: [func1], //func2 depends on func1 
    func3: [func2], 
    func4: [func1, func3] //func4 depends on both func1 and func3 
}); 

callManager.callAsynchronous(); 

Con la configurazione corrente di cui sopra, quando viene eseguito l'output è dato come -

Calling....func2 
Dependant call ... 1 
Dependant call ... 2 
Calling....func3 
Dependant call ... 2 
Dependant call ... 3 
Calling....func4 
Dependant call ... 1 
Dependant call ... 3 
Dependant call ... 4 
+1

E se hai bisogno di passare i parametri, cambia i codici per prendere i parametri del tuo desiderio, –

Problemi correlati