2014-06-23 11 views
21

Ich habe einen Service namens PaymentStrategy, die in meinem Controller injiziert werden.Kette verspricht mit AngularJS

$scope.buy = function() { 
    paymentStrategy.buy() 
    .then(function(response) { 

    } 
} 

Diese Kaufmethode von paymentStrategy löst mehrere Methoden aus, die nacheinander aufgerufen werden müssen. Wenn alle Methoden innerhalb von buy() erledigt sind, muss() aufgerufen werden.

Es ist wahrscheinlich trivial, aber ich bin ziemlich neu zu eckig.

Momentan wird buy(). Then() direkt nach den init() Methoden ausgelöst. Ich habe das Gefühl, wir müssen alle diese Methoden in eine Reihe von Versprechen setzen und $ q.all() anwenden.

Jede Hilfe oder Anregungen wäre sehr

geschätzt werden
angular.module('deps-app.payment.services', []). 
    factory('paymentStrategy', function($q) { 

var deferred = $q.defer(); 
var ITEM_TO_PURCHASE = "test.beer.managed"; 
var promises = []; 

var handlerSuccess = function(result) { 
     deferred.resolve(result); 
    }; 

var handlerError = function(result) { 
     deferred.reject(result); 
    }; 

_init = function() { 

    inappbilling.init(handlerSuccess, handlerError, { showLog:true }); 
    return deferred.promise; 
    } 

    _purchase = function() { 
     inappbilling.buy(handlerSuccess, handlerError, ITEM_TO_PURCHASE); 
     return deferred.promise; 
    } 

    _consume = function() { 
     inappbilling.consumePurchase(handlerSuccess, handlerError, ITEM_TO_PURCHASE); 
     return deferred.promise; 
    } 

return { 

    buy: function() { 

     _init(); 
     .then(_purchase()); 
     .then(_consume()); 

     return deferred.promise;      
    } 

} 
}); 
+1

Haben Sie alle Methoden auf Inappbilling wie init, buy und consumePurchase Rückgabe Versprechen? – Chandermani

+0

Hört sich gut an, aber kannst du bitte den Weg erklären? –

+0

Das war eine Frage an dich Florent. Das Problem mit Ihrem Code besteht darin, dass Sie das Versprechen beim Init-Callback und bei anderen Callbacks ebenfalls lösen, aber Sie müssen warten, bis alle Anrufe abgeschlossen sind, bevor Sie den Resolve aufrufen. – Chandermani

Antwort

19

Machen Sie alle Methoden atomar, indem sie ihre eigenen Versprechen hinzufügten. In Ihrem Code wird die erste resolve die gesamte Anfrage abschließen.

Wenn die Methoden ihr eigenes Versprechen haben, können Sie sie leicht verketten.

angular.module('deps-app.payment.services', []).factory('paymentStrategy', function($q) { 
var ITEM_TO_PURCHASE = "test.beer.managed"; 

_init = function() { 
    return $q(function (resolve, reject) { 
    inappbilling.init(resolve, reject, { showLog: true }); 
    }); 
}; 

_purchase = function() { 
    return $q(function (resolve, reject) { 
    inappbilling.buy(resolve, reject, ITEM_TO_PURCHASE); 
    }); 
}; 

_consume = function() { 
    return $q(function (resolve, reject) { 
    inappbilling.consumePurchase(resolve, reject, ITEM_TO_PURCHASE); 
    }); 
}; 

return { 
    // In this case, you don't need to define a additional promise, 
    // because placing a return in front of the _init, will already return 
    // the promise of _consume. 
    buy: function() {  
    return _init() 
     .then(_purchase) 
     // remove() from inside the callback, to pass the actual method 
     // instead the result of the invoked method. 
     .then(_consume);  
    }  
}; 

});

+0

Vielen Dank für Ihre Hilfe, sehr geschätzt. Eine Frage vor der Annahme. Es scheint, dass es nie in die (...) Methode buy() geht. Ist es ein guter Weg, das so zu machen? : _init() .then (_consumeAll) .then (_purchase) .then (_consume) .then (deferred.resolve) –

+0

ah mein Fehler. check now –

+1

Mit '$ q.defer()' ist [_allest always_ bad practice] (http://www.codelord.net/2015/09/24/$q-dot-defer-youre-doing-it-wrong) /), und das ist keine Ausnahme. Jede der drei Funktionen könnte vereinfacht werden, indem man etwa wie folgt vorgeht: _ _init = function() {return $ q (Funktion (auflösen, ablehnen) {inappbilling.init (auflösen, ablehnen, {showLog: true});}); }; ', die ein Versprechen wie gewünscht zurückgibt. Im Idealfall sollten die Methoden zur "Nichtanpassung" Versprechungen zurückgeben (die einfach von Ihren _init-, usw.-Methoden zurückgegeben werden), aber ich nehme an, dass dies möglicherweise nicht Ihre Entscheidung ist. –

46

Wenn Sie an die Kette Versprechen in Angular sequentiell benötigen, können Sie einfach die Versprechungen von einem zum anderen zurück:

callFirst() 
.then(function(firstResult){ 
    return callSecond(); 
}) 
.then(function(secondResult){ 
    return callThird(); 
}) 
.then(function(thirdResult){ 
    //Finally do something with promise, or even return this 
}); 

Und wenn Sie möchte all das als API zurückgeben:

function myMethod(){ 
    //Return the promise of the entire chain 
    return first() 
      .then(function(){ 
       return second(); 
      }).promise; 
} 
+0

Ich bin neu zu versprechen und auch eckig. hier die erste dann zurück ruft zweitens dann aber es gibt Methode zurück, tatsächlich zweite nimmt dann den Wert als Argument rechts.Ich weiß nur C, also bin ich mir nicht sicher. – santhosh

+1

So einfach und so mächtig! Vielen Dank. Ich habe verstanden, was ich zu tun habe, erst nachdem ich deinen Beitrag gelesen habe. Alle anderen Beispiele, die ich fand, waren so kompliziert. – tarekahf