Angular - .finally() 是否在链式承诺决策树中的每条路径的末尾调用?
Angular - Is .finally() Called At the End of Every Path in a Chained Promise Decision Tree?
我有以下连锁的承诺序列:
$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;
});
无论前两个promise成功/失败,是否都在最后调用了finally()
回调函数?
例如,如果 myFirstPromise()
return 发出 400 响应,mySecondPromise()
将永远不会被调用 - 但我假设 finally()
块仍会被抛出?如果 mySecondPromise()
returns a 400(并且 $scope.secondResponse
从未设置)并且如果两个承诺 return 200s.
Angular 1.x $q
服务灵感来自 Kris Kowal 的 Q,基于 docs:
finally(callback, notifyCallback) – allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information.
所以是的,无论 myFirstPromise
解决还是拒绝,finally()
块都会被调用
已更新,
请注意,myFirstPromise
的 finally()
块将在 mySecondPromise
解决(或拒绝)之前调用,因为 myFirstPromise
和 mySecondPromise
是不同的 promise 实例,mySecondPromise
在 myFirstPromise
解决后创建的 promise 实例
我写了一个 Jasmine 测试来查看 finally()
块是否在每个函数执行时被调用,无论链接的承诺返回什么。
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();
});
});
});
以上假设控制器看起来像:
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;
});
}
});
即使您在我们定义 myService
.[=18 的 beforeEach()
回调中将任何或所有 deferred.resolve()
更改为 deferred.reject()
,以上内容也会通过=]
我有以下连锁的承诺序列:
$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;
});
无论前两个promise成功/失败,是否都在最后调用了finally()
回调函数?
例如,如果 myFirstPromise()
return 发出 400 响应,mySecondPromise()
将永远不会被调用 - 但我假设 finally()
块仍会被抛出?如果 mySecondPromise()
returns a 400(并且 $scope.secondResponse
从未设置)并且如果两个承诺 return 200s.
Angular 1.x $q
服务灵感来自 Kris Kowal 的 Q,基于 docs:
finally(callback, notifyCallback) – allows you to observe either the fulfillment or rejection of a promise, but to do so without modifying the final value. This is useful to release resources or do some clean-up that needs to be done whether the promise was rejected or resolved. See the full specification for more information.
所以是的,无论 myFirstPromise
解决还是拒绝,finally()
块都会被调用
已更新,
请注意,myFirstPromise
的 finally()
块将在 mySecondPromise
解决(或拒绝)之前调用,因为 myFirstPromise
和 mySecondPromise
是不同的 promise 实例,mySecondPromise
在 myFirstPromise
解决后创建的 promise 实例
我写了一个 Jasmine 测试来查看 finally()
块是否在每个函数执行时被调用,无论链接的承诺返回什么。
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();
});
});
});
以上假设控制器看起来像:
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;
});
}
});
即使您在我们定义 myService
.[=18 的 beforeEach()
回调中将任何或所有 deferred.resolve()
更改为 deferred.reject()
,以上内容也会通过=]