4

我正在重构一个使用传统回调模式的资源加载函数来代替使用 jQuery Deferreds。

这个函数接受 url 数组,为每个资源创建一个新的 Deferred 对象,创建一个$.whenDeferred 对象来监视它们,并返回该$.when对象的 Promise。

这是该方法的简化版本:

theLib = {
    getResources : function(paths) {
        var deferreds = [];
        theLib.isLoading = true;
        $.each(paths, function(i, path) {
            // do something with the path, either using getScript
            // or making a new $.Deferred as needed
            deferreds.push(/* the deferred object from above comment */);
        });
        theLib.currentDeferred = $.when.apply(null,deferreds).always(function() {
            theLib.isLoading = false;
        });

        return theLib.currentDeferred.promise();
};

这很好用。

我的问题:在旧脚本中,不仅会theLib.getResources()基于用户操作或事件进行调用,而且还会定义一个主资源列表,当用户不采取任何操作(即阅读一篇文章)时应用程序将“流式传输”这些资源)。

当用户采取行动时其中一些流式资源将与可以手动调用的资源相同。该脚本足够聪明,不会通过跟踪加载的内容来两次加载资源。

它还跟踪theLib.isLoading. 该函数的开头看起来像这样:

getResources : function(paths, callback) {
    if (theLib.isLoading) {
        settimeout(function() {
            theLib.getResources(paths, callback);
        }, 100);
    }
    theLib.isLoading = true;

我不能再这样做了,因为我需要返回一个 Promise 对象。

我知道我可以检查theLib.currentDeferred.isResolved()。那时,如果没有解决:如何将更多延迟对象添加到$.when正在监视的队列中?

4

1 回答 1

3

我想我需要问这个问题才能为自己找到解决方案。基本上我在开头添加了以下代码getResources

if ( ! theLib.currentDeferred.isResolved()) { return $.when(theLib.currentDeferred).always(function() { theLib.getResources(paths); }).promise(); }

以上是失败的。正确的解决方案是管道结果:

if ( ! theLib.currentDeferred.isResolved()) {
    return theLib.currentDeferred.pipe(function() {
        return theLib.getResources(paths);
    });
}
于 2011-06-05T14:36:56.920 回答