2014-05-20 3 views
7

Ich bin etwas neu zu versprechen und stecken auf der folgenden Übung.Verkettung verschachtelten Versprechen in einer Schleife

Ich habe ein Array von Werten und ich möchte auf jedem einen asynchronen Aufruf ausführen. Im Rückruf möchte ich einen weiteren Anruf auf das Ergebnis des ersten Anrufs ausführen.

Grundsätzlich meine Frustration in der folgenden ist: Die Reihenfolge der Ausführung sein ‚1x2x3x‘ sollte aber die Reihenfolge ist ‚123xxx‘

Mit anderen Worten, wird die Schleife geht bereits auf die nächste Iteration, wenn die Unter/verschachtelte Versprechen der ersten Versprechen noch nicht erfüllt ..

var values = ["1", "2", "3"]; 

function do(val) { 
    var deferred = Q.defer(); 


    asyncCall(val) 
    .then(function(response) { 
    console.log(val); 
    asyncCall(response) 
    .then(function (response) { 
     console.log('x'); 
     deferred.resolve(true) 
    }); 
    }); 

    return deferred.promise; 
} 

var result = do(values[0]); 

values.forEach(function(f) { 
    result = result.then(do(f)); 
} 

es gibt wohl eine einfache Lösung, aber ich bin auf sie stecken.

Antwort

5

Sie brauchen nicht die aufgeschobene, das ist die deferred anti pattern Sie haben da seit Versprechungen Kette.

Außerdem müssen Sie eine Zusage von einem .then-Handler zurückgeben, wenn Sie warten möchten, bis der Fehler behoben ist.

Sie können einfach eine for-Schleife verwenden:

function do(val) { 

    var q = Q(); 
    for(var i = 0; i < val; i++){ 
    q = q.then(asyncCall.bind(null,i)) 
     .then(console.log.bind(console)) 
     .then(console.log.bind(console,"x")); 
    } 

    return q; // in case you want to chain 
} 

fiddle.

Hinweis: Bindung fixiert nur den Wert für den Funktionsaufruf. In diesem Fall, da der erste Parameter (der this Wert) null ist, verhält er sich wie function(fn,arg){ return function(arg){ return fn(arg); }} das heißt, er übersetzt einen Funktionsaufruf in eine "partielle Anwendung" - für weitere Informationen siehe the MDN docs.

+0

Vielen Dank für Ihre Antwort. – strai

+0

Vielen Dank für Ihre Antwort. Aber ich verstehe das nicht ganz. Ich habe das latente Muster entfernt und Refactoring mein Code wie folgt: Funktion (Wert) abrufen { return asyncCall (Wert) .then (function (Antwort) { console.log (Antwort); return response.asyncCall2 (); }) .then (Funktion (Antwort) { console.log (Antwort); }); } Ich kann die Rückkehr in den ersten ‚und dann‘ verlassen, aber dann das Versprechen asyncCall2 nicht dann an die zweite übergeben .. – strai

+0

@strai können Sie eine Geige auf jsfiddle.net schaffen das Problem darstellt? Das ist schwer zu lesen –