用jQueryDeferred对象制作多个脚本加载器,我做得对吗
Making multiple scripts loader with jQuery Deferred object, am I doing it right?
我正在开发一个更好版本的$.getScript
函数,它可以:
- 一次加载多个脚本
- 缓存已加载的脚本
- 加载所有必需的脚本后触发回调
您可能会建议使用一些库,如requirejs或LABjs,但我认为我可以通过使用jQueryDeferred对象来创建类似的库。这是我迄今为止的尝试:
(function($) {
'use strict';
var cachedScriptPromises = {};
$.require = function(url, callback, errback) {
var urls = (url instanceof Array) ? url : [url],
promises = [];
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
if ( ! cachedScriptPromises[url]) {
cachedScriptPromises[url] = $.Deferred(function(defer) {
$.ajax({
dataType: 'script',
cache: true,
url: url
}).then(defer.resolve, defer.reject);
}).promise();
}
promises.push(cachedScriptPromises[url]);
}
$.when.apply($, promises).done(callback).fail(errback);
};
})(jQuery);
其想法是为每个脚本url存储一个promise对象,然后在解析所有延迟对象时触发回调。
我不知道如何正确测试这个功能,但请看一下这个测试页面,如果你多次刷新页面,其中一个输出可能会丢失(在Chrome上比Firefox上更常见)
更新-下面是我的一个测试用例,它有时没有记录任何内容:
$.require(['jquery.log.js', 'foo.js'], function() {
$('#log').log('jquery.log.js and foo.js were loaded!');
});
jquery.log.js:
(function($) {
$.fn.log = function(msg) {
this.each(function() {
$(this).append('<p>' + msg + '</p>');
});
};
})(jQuery);
foo.js:
$('#log').log('Foo!');
那么我的$.require
函数有什么问题吗?
问题是jquery.log.js和foo.js将并行加载。如果首先加载foo.js,它将抛出一个错误(日志函数未定义)。所以我必须把$.require
放在foo.js:上
$.require('jquery.log.js').done(function() {
$('#log').log('Foo!');
});
关于我对jQuery Deferred对象做得对吗?以下是@Benjamin Gruenbaum建议的一些更改:
$.ajax
返回一个promise,所以不需要将其封装在一个新的延迟对象中- 使用promise对象可以获得更好的可读代码,因此
$.require
函数应该返回promise,而不是使用回调/errback
更改后的$.require
功能:
(function($) {
'use strict';
var cachedScriptPromises = {};
$.require = function(url) {
var urls = (url instanceof Array) ? url : [url],
promises = [];
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
if ( ! cachedScriptPromises[url]) {
cachedScriptPromises[url] = $.ajax({
dataType: 'script',
cache: true,
url: url
});
}
promises.push(cachedScriptPromises[url]);
}
return $.when.apply($, promises);
};
})(jQuery);
相关文章:
- Google Adsense多次加载脚本
- 如何准确执行加载脚本&退出弹出窗口
- RequireJ无法随机加载脚本
- 通过浏览器加载页面时触发加载脚本(js或jQuery)'s”;返回“;作用
- 在以前的文件夹中加载脚本
- 如何重新加载脚本标记
- 正在脚本中加载脚本
- 在pjax完成其工作时加载脚本
- I'我用setTimeout加载脚本,你能找到一个更快的方法吗
- 在页面模板上加载脚本
- 如何在我的情况下创建加载脚本
- 当用$.getScript()加载脚本时,有一种方法可以从用$.get script()装载的脚本中调用父脚本中的函数
- 延迟加载 脚本加载和/或执行
- 如何使用谷歌页面速度CSS加载脚本延迟多个CSS文件
- 最后加载脚本
- 如何基于HTML中的类加载脚本
- 在局部视图中加载脚本文件
- 如何防止在使用hapi.js reply().hold()时重新加载脚本
- 异步加载脚本
- 脚本加载脚本广告