避免在Angular.js中重复异步服务初始化

Avoiding duplicate asynchronous service initialisations in Angular.js

本文关键字:异步 服务 初始化 Angular js      更新时间:2023-09-26

我有一个异步交付结果的Angular.js服务,在看了一段时间后,做这件事的主要模式似乎是使用像这样的$q承诺

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();
            }
        }
    }
});

问题是,我有许多服务,有这个服务作为一个依赖关系,并在第一个longAsyncInit结束之前多次调用get(这意味着longAsyncInit被调用多次,每次创建一个新的承诺)。在我的情况下,这是不可接受的,我真的需要longAsyncInit调用一次,而不是更多。我现在是这样处理这个问题的

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();
            }
        }
    }
});

这意味着当get()调用时,如果longAsyncInit已经在进行中,它返回当前的承诺,而不是创建一个新的并再次调用longAsyncInit。这似乎是工作,但感觉不优雅和脆弱,有没有更好的方式做到这一点?

您正在寻找debounce方法来解决问题。

来自下划线库文档_.debounce()做什么

创建并返回传递的函数的新去绑定版本这将延迟其执行,直到等待毫秒有自上次调用它以来所经过的时间。对实现有用只有在输入停止到达后才应该发生的行为。例如:呈现Markdown注释的预览,重新计算窗口停止调整大小后的布局,等等。

  • 更多的解释有人能解释一下"脱线"吗?

  • 一些内容要读:http://davidwalsh.name/javascript-debounce-function