I guess I don't believe in myself as a good programmer but I found out this method on my own (not suggestion I'm the first one to do it, but I didn't follow a guide) so it must be broken somehow.
$q is mainly a callback kind of service for async reasons, but it served me in another way as well.
I might have multiple calls to a long running service, but I only need a response once. So I want to disregard all calls except from the first one and cache the result from that and return to everybody.
If I give everybody a promise when called they get the result when the promise is resolved, even if it was resolved before the promise was actually given, that's a nice feature.
So I could only make the dervice call the first time I give the promise.
myApp.factory('serviceWithLongCall', function ($q, $timeout) {
var data = {}
var hasStarted = false;
var deferred = $q.defer();
return {
call: call
};
function call() {
if (!hasStarted) {
hasStarted = true;
console.log('timeout started');
$timeout(function () {
console.log('timeout ended');
data = 42;
deferred.resolve(data);
}, 3000);
}
return deferred.promise;
}
});
fiddle with example, click some buttons and wait for 3 seconds from first click, later clicks will happen instantly.
Is something off with this method, will I have a race condition?
Best Answer
Returning the same promise from a call multiple times for caching reasons is absolutely fine. No race condition that I can think of, and I've used that technique with no issue.
The only small issue with you code is that's it's unnecessary to create the deferred object.
$timeout
returns a promise that can resolve to the value you want.Admittedly your use of
$timeout
might be just for example reasons, but I suspect you can do the same thing with$http
.