Reputation: 262
i have write one service like that :
pinholeAdminServices.factory('ServiceChannel', ['Channel', '$httpWrapper' , '$route', '$q' , function (Channel, $httpWrapper, $route, $q) {
'use strict';
return {
'MultiChannelsLoader': function (params) {
params = params || $route.current.params;
var delay = $q.defer();
Channel.query(params, function (response) {
delay.resolve(response);
}, function (error) {
delay.reject(error);
});
return delay.promise;
}
}
}]);
and after that i have change the place of var delay = $q.defer();
in the top of service like that :
Services.factory('ServiceChannel', ['Channel', '$httpWrapper' , '$route', '$q' , function (Channel, $httpWrapper, $route, $q) {
'use strict';
var delay = $q.defer();
return {
'MultiChannelsLoader': function (params) {
params = params || $route.current.params;
Channel.query(params, function (response) {
delay.resolve(response);
}, function (error) {
delay.reject(error);
});
return delay.promise;
}
}
}]);
and the application behavior became totally wrong. can anyone explain what's the difference between the two part's of code
Upvotes: 1
Views: 83
Reputation: 276306
This creates one deferred for every ServiceChannel usage.
This means, that when you call MultiChannelsLoader
it will use the same promise each time.
A promise is an abstraction over a one time calculation. After it is resolved a promise can not change its state.
var d = $q.defer();
d.resolve("Foo"); // d will forever be remained in fulfilled state, with "Foo"
Imagine that resolve is implemented as:
resolve: function(){
if(pending){ // not resolved yet
pending = undefined; // change state to not pending.
}
}
Oh wait, it actually is. The promise specification is also crystal clear about this:
When fulfilled, a promise: must not transition to any other state. When rejected, a promise: must not transition to any other state.
Upvotes: 3