0

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?

jbat100
  • 16,757
  • 4
  • 45
  • 70

1 Answers1

0

You are looking for debounce method to solve problem.

From Underscore library documentation what _.debounce() do

Creates and returns a new debounced version of the passed function which will postpone its execution until after wait milliseconds have elapsed since the last time it was invoked. Useful for implementing behavior that should only happen after the input has stopped arriving. For example: rendering a preview of a Markdown comment, recalculating a layout after the window has stopped being resized, and so on.

Community
  • 1
  • 1
Krzysztof Safjanowski
  • 7,292
  • 3
  • 35
  • 47