2014-06-23 12 views
21

Mam usługę o nazwie paymentStrategy, która zostanie wprowadzona do mojego kontrolera.Łańcuchowe obietnice z AngularJS

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

    } 
} 

Ta metoda zakupu z paymentStrategy uruchamia kilka metod, które należy nazywać sekwencyjnie. Po wykonaniu wszystkich metod w funkcji purchase() należy wywołać metodę().

Jest to prawdopodobnie trywialne, ale jestem nowy w kanciastym.

W tej chwili buy(). Then() zostaje wyzwolony bezpośrednio po metodach init(). Mam wrażenie, że musimy umieścić wszystkie te metody w szeregu obietnic i zastosować $ q.all().

Każda pomoc lub sugestie będą bardzo mile widziane

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

Czy wszystkie metody inappbilling, takie jak init, buy i consumePurchase obietnica zwrotu? – Chandermani

+0

Brzmi nieźle, ale czy możesz wyjaśnić, jak to zrobić? –

+0

To było dla ciebie pytanie Florent. Problem z kodem polega na tym, że rozwiązuje się obietnicę wywołania zwrotnego init i innych wywołań zwrotnych, ale przed wywołaniem rozwiązania należy poczekać na zakończenie wszystkich połączeń. – Chandermani

Odpowiedz

19

Spraw, aby wszystkie metody były atomowe, poprzez dodanie własnych obietnic. W Twoim kodzie pierwszy resolve zakończy całe żądanie.

Jeśli metody mają swoją własną obietnicę, możesz łączyć je z łatwością.

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

Dziękuję bardzo za pomoc, bardzo doceniane. Jedno pytanie przed zaakceptowaniem. Wydaje się, że nigdy nie wchodzi on wtedy (..) w metodę buy(). Czy to dobry sposób na zrobienie tego w ten sposób? : _init() .then (_consumeAll) .then (_purchase) .then (_consume) .then (deferred.resolve) –

+0

ah moja pomyłka. sprawdź teraz –

+1

Używanie '$ q.defer()' jest [_almost always_ bad practice] (http://www.codelord.net/2015/09/24/$q-dot-defer-youre-doing-it-wrong /) i nie jest to wyjątkiem. Każdą z trzech funkcji można uprościć, wykonując operację '_init = function() {return $ q (funkcja (rozstrzygnięcie, odrzucenie) {inappbilling.init (rozstrzygnięcie, odrzucenie, {showLog: true});}); }; ', który zwróci obietnicę według życzenia. Idealnie, metody "inappbilling" powinny zwracać obietnice (które są po prostu zwracane przez twoje metody _init, itp.), Ale przypuszczam, że może to nie być twoja decyzja do zrobienia. –

46

Jeśli trzeba obietnic łańcuchowych kątowej sekwencyjnie, można po prostu wrócić obietnice z jednego do drugiego:

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

a jeśli chcesz to wszystko zwrócić jako API:

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

Jestem nowy w obiecywaniu i również kanciasty. tutaj pierwszy następnie wywołuje drugie wywołanie, ale jest to metoda zwracająca, w rzeczywistości druga przyjmuje wartość jako argument prawy. Wiem tylko C, więc nie jestem pewien. – santhosh

+1

Tak prosty i tak potężny! Dziękuję Ci. Zrozumiałem, co muszę zrobić, dopiero po przeczytaniu twojego posta. Wszystkie inne znalezione przykłady były tak skomplikowane. – tarekahf