我正在重构一个资源加载函数,该函数使用传统的回调模式代替使用jQuery Deferreds。
此函数获取和数组url,为每个资源创建一个新的Deferred对象,创建一个$.when
Deferred对象来观察它们,并返回$.when
对象的承诺。
以下是该方法的简化版本:
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
队列中?
答案 0 :(得分: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);
});
}