2013-04-17 11 views
32

Próbuję połączyć wiele odroczonych wywołań funkcji tak, że następne wywołanie uzyskuje wyniki poprzedniego odroczonego .resolve. Kiedy połączę więcej niż 2 z tych połączeń, dane przestaną być zwracane.Wiele odroczonych funkcji odroczonych za pomocą q w AngularJS przestań zwracać dane

Oto podstawowy kod wewnątrz kątowym regulatora:

$scope.runAsync = function() { 
     var asyncFn1 = function(data){ 
      var deferred = $q.defer(); 

      $timeout(function(){ 
       console.log("Async fn1 " + data); 
       $scope.outputLines.push("Async fn1 " + data); 
       deferred.resolve("Async fn1 " + data); 
      },1000); 

      return deferred.promise; 
     } 

     var asyncFn2 = function(data){ 
      var deferred = $q.defer(); 

      $timeout(function(){ 
       console.log("Async fn2 " + data); 
       $scope.outputLines.push("Async fn2 " + data); 
       deferred.resolve("Async fn2 " + data); 
      },1000); 

      return deferred.promise; 
     } 

     asyncFn1(1) 
     .then(function(data){asyncFn2(data)}) 
     .then(function(data){asyncFn2(data)}) 
     .then(function(data){asyncFn2(data)}); 
    } 

Gdy uruchomię to pojawia się następujący komunikat:

Async fn1 1 
Async fn2 Async fn1 1 
Async fn2 undefined 
Async fn2 undefined 

Jak mogę łańcucha je razem tak, że trzeci wezwanie dostaje wynik z drugiego połączenia, a czwarty otrzymuje wynik z trzeciego?

Stworzyłem jsFiddle: http://jsfiddle.net/rhDyL/

Odpowiedz

40

Fragment zaczerpnięty z oficjalnej doc na $ Q:

następnie (successCallback, errorCallback) - niezależnie od tego, kiedy obietnica został lub zostanie rozwiązana lub odrzucono wywołanie asynchronicznie, gdy tylko wynik jest dostępny, wywołuje jeden z ponownych wywołań błędów lub powodzenia . Wywołania zwrotne są wywoływane z jednym argumentem powodu lub odrzucenia.

Ta metoda zwraca nową obietnicę, która jest rozwiązana lub odrzucona przez zwracaną wartość successCallback lub errorCallback.

A o wartości powrotnej successCallack lub errorCallback według Domenic's slides:

jeśli wartość zwracana jest obietnica to obietnica przyjmuje stan zwracanego Promise inaczej zwrotna sukces jest natychmiast o nazwie z wartością zwracaną

W oparciu o definicję w Twoim kodzie brakuje słowa kluczowego return. Powinno być następujące:

asyncFn1(1) 
    .then(function(data){return asyncFn2(data)}) 
    .then(function(data){return asyncFn2(data)}) 
    .then(function(data){return asyncFn2(data)}); 
+0

Wow .. dzięki. Widzę to teraz. Jestem po prostu zdezorientowany faktem, że metoda .then() zwraca nową obietnicę, ale wewnątrz asyncFn zwracam obietnicę z odroczonego obiektu. Wydaje się, że liczba obietnic jest dwukrotnie większa. – BoxerBucks

+2

Niedawno byłem w tej samej pozycji. _Promise & deferred_ wymaga trochę krzywej uczenia się i praktyki, aby się przyzwyczaić. Niemniej jednak myślę, że warto. Dzięki temu zarządzanie kodowaniem w świecie asynchronicznego programowania jest o wiele łatwiejsze. Jeśli nadal nie jesteś zaznajomiony z tematem, bardzo polecam [to czytanie] (http://www.slideshare.net/domenicdenicola/promises-promises). – tamakisquare

+1

@tamakisquare - dzięki za odpowiedź i komentarz. Myślę, że kluczowym punktem zamieszania, który jest wyjaśniony na slajdzie nr 7 [prezentacji domeny] (http://www.slideshare.net/domenicdenicola/promises-promises) jest to, że jeśli wartość zwrotu jest obietnicą, wówczas obietnica przyjmuje wrócił stan obietnicy, w przeciwnym razie oddzwanianie powodzenia jest natychmiast wywoływane z wartością zwracaną. Być może możesz zmodyfikować swoją odpowiedź, aby to odzwierciedlić - aby była bardziej kompletna. Dzięki. – Amir

Powiązane problemy