I have an Angular.js service which delivers its results asynchronously, after looking around for a while the main pattern for doing this seems to be using $q promises like this
angular.module('fooApp').factory('foo', function ($q) {
var result;
function build() {
var d = $q.defer();
longAsyncInit(function(data) {
result = data;
d.resolve(result);
});
return d.promise;
};
return {
get: function () {
if (result) {
return $q.when(result);
} else {
return build();
}
}
}
});
The problem is that I have a number of services which have this service as a dependency and get is called multiple times before the first longAsyncInit ends (which means that longAsyncInit gets called multiple times, each time creating a new promise). In my case this is unacceptable, I really need longAsyncInit to be called once, no more. I'm currently addressing this issue like this
angular.module('fooApp').factory('foo', function ($q) {
var result
var d;
function build() {
d = $q.defer();
longAsyncInit(function(data) {
result = data;
d.resolve(result);
});
return d.promise;
};
return {
get: function () {
if (result) {
return $q.when(result);
} else if (d) {
return d.promise;
} else {
return build();
}
}
}
});
This means if longAsyncInit is already ongoing when a get() call is made, it returns the current promise, instead of creating a new one and calling longAsyncInit again. This seems to work but feels inelegant and fragile, is there a better way of doing this?