2016-05-06 10 views
3

Ich habe folgende verkettete Folge von Versprechen:Angular - Wird .finally() am Ende jedes Pfades in einem Chained Promise Decision Tree aufgerufen?

$scope.promisesInProgress = true 
myService.myFirstPromise(id) 
    .then(function(data){ 
     $scope.firstResponse = data; 
     return myService.mySecondPromise(id); 
    }) 
    .then(function(data){ 
     $scope.secondResponse = data; 
    }) 
    .finally(function(){ 
     $scope.promisesInProgress = false; 
    }); 

Ist finally() Callback-Funktion ganz gleich ganz am Ende genannt wird, was der Erfolg/Misserfolg der vergangenen zwei Versprechen ist?

Zum Beispiel, wenn myFirstPromise() eine 400-Antwort zurückgegeben, mySecondPromise() wird nie genannt werden - aber ich nehme an, der finally() Block noch geworfen werden würde? Dasselbe sollte wahr sein, wenn mySecondPromise() eine 400 zurückgibt (und $scope.secondResponse wird nie gesetzt) ​​und wenn beide Versprechen 200s zurückgeben.

Antwort

0

Ich schrieb einen Jasmine-Test, um zu sehen, ob der finally()-Block bei jeder Funktionsausführung aufgerufen wird, egal was die verketteten Versprechen zurückgaben.

describe('myController Test Suite', function(){ 

    var q, scope, deferred, myService; 

    // Initialize the Pointivo module 
    beforeEach(function(){ 
     module('myApp'); 
    }); 

    // Mock out fake service 
    beforeEach(function(){ 
     myService = { 
      myFirstPromise: function(){ 
       deferred = q.defer(); 
       // TEST ME 
       deferred.resolve('first promise response'); 
       return deferred.promise; 
      }, 
      mySecondPromise: function(){ 
       deferred = q.defer(); 
       // TEST ME 
       deferred.resolve('second promise response'); 
       return deferred.promise; 
      }, 
      myThirdPromise: function(){ 
       deferred = q.defer(); 
       // TEST ME 
       deferred.resolve('third promise response'); 
       return deferred.promise; 
      } 
     }; 
     spyOn(myService, 'myFirstPromise').and.callThrough(); 
     spyOn(myService, 'mySecondPromise').and.callThrough(); 
     spyOn(myService, 'myThirdPromise').and.callThrough(); 
    }); 

    // Assign controller scope and service references 
    beforeEach(inject(function($controller, $rootScope, $q){ 
     scope = $rootScope.$new(); 
     q = $q; 
     $controller('myController', { 
      $scope: scope, 
      myService: myService 
     }); 
    })); 

    describe('finally test', function(){ 
     it('should always hit the finally statement', function(){ 
       scope.finallyStatementFlag = false; 
      scope.test(); 
      scope.$apply(); 
      expect(scope.finallyStatementFlag).toBeTruthy(); 
     }); 
    }); 

}); 

Die oben beruht auf der Annahme, dass die Steuerung wie folgt aussieht:

myApp.controller('myController', function($scope, myService){ 

    $scope.finallyStatementFlag = false; 

    $scope.test = function(){ 
     myService.myFirstPromise() 
      .then(function(data){ 
       console.log(data); 
       return myService.mySecondPromise() 
      }) 
      .then(function(data){ 
       console.log(data); 
       return myService.myThirdPromise(); 
      }) 
      .then(function(data){ 
       console.log(data); 
      }) 
      .finally(function(){ 
       console.log('finally statement'); 
       $scope.finallyStatementFlag = true; 
      }); 
    } 

}); 

Die oben wird passieren, auch wenn Sie einige oder alle der deferred.resolve()-deferred.reject() innerhalb des beforeEach() Rückruf ändern, wo wir definieren myService.

Fiddle example

0

Angular 1.x $q Service inspiriert von Kris Kowal des Q, basierend auf docs:

schließlich (Rückruf, notifyCallback) - Sie entweder die Erfüllung oder Ablehnung eines Versprechen zu beobachten erlaubt, aber dies zu tun ohne den endgültigen Wert zu ändern. Dies ist nützlich, um Ressourcen freizugeben oder eine Bereinigung vorzunehmen, die ausgeführt werden muss, unabhängig davon, ob das Versprechen abgelehnt oder aufgelöst wurde. Weitere Informationen finden Sie in der vollständigen Spezifikation.

also ja, ganz gleich myFirstPromise aufgelöst oder abgelehnt, der finally() Block immer

genannt würde

AKTUALISIERT

bemerkt zu werden, der finally() Block myFirstPromise würde vor mySecondPromise aufgelöst aufgerufen werden (oder abgewiesen), da myFirstPromise und mySecondPromise verschiedene Promise-Instanzen sind und mySecondPromise Promise-Instanzen nach myFirstPromise aufgelöst

erstellt wurden
Verwandte Themen