2014-05-20 6 views
7

Mam funkcję asynchroniczną, która działa z wynikiem dwóch innych funkcji asynchronicznych.Jak obsługiwać funkcję asynchroniczną, która zależy od wielu innych funkcji asynchronicznych

Do tej pory, co robię jest to, że piszę function2 w Function1 zwrotnego i function2 w zwrotnego z function2

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

Czy jest jakiś inny sposób, aby sobie z tym poradzić. Pracuję zwykle z kodem JavaScript po stronie klienta i w węźle nodeJs.

Mój scenariusz jest taki, że dla funkcji 2 nie potrzebuję wyjścia z funkcji1. Innymi słowy funkcja 1 i funkcja 2 są niezależne; ale funkcja 3 zależy od funkcji 1 i funkcji 2.

Chcę, aby moja funkcja 2 działała niezależnie od funkcji 1, ale funkcja 3 działała w zależności zarówno od funkcji 1, jak i od funkcji2.

Czy istnieje coś takiego jak

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

Masz prawo pomysł. Jeśli zmęczy Cię coraz więcej zagnieżdżania, spójrz na bibliotekę async.js w npm. To, co masz, jest obsługiwane przez pomocnika "serii" w async.js https://github.com/caolan/async#seriestasks-callback – Paul

+0

@Paul Wprowadziłem kilka zmian w pytaniu, czy możesz to rozważyć. – Okky

+1

Wygląda na to, że Jacob napisał już świetną odpowiedź ...! – Paul

Odpowiedz

6

Istnieje kilka dobrych bibliotek do czynienia z wzniecanie funkcji asynchronicznych. Pomoc: async i q (lub inne promises/A library).

Jeśli function2 nie zależy od wyniku function1, można wykonać je równolegle. Oto jak to wygląda przy użyciu async (przykłady te zakładają, że zwrotna ma function(err, result) podpis, który stanowi wzór defacto dla węzła:

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

Jeśli function2 zależy od wyniku z function1, waterfall może być lepszy wzór:

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

Osobiście lubię q, ponieważ można przekazać obietnic wokół i robić różnego rodzaju przydatne rzeczy Oto jak to wygląda przy użyciu tego.

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

Lub jeśli function1 i function2 może być wykonane w dowolnej kolejności:

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

co z przekazywaniem wyników do funkcji 2? –

2

Oto rozwiązanie, które upiekłam. Można spróbować menedżera połączeń, aby wywołać funkcje zależne

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

Przy obecnej konfiguracji przedstawiono powyżej, gdy prowadzony jest wyjście jest podany jako -

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

A jeśli potrzebujesz przekazać parametry, po prostu zmień kody, aby dostosować parametry swojego życzenia, –

Powiązane problemy