jquery.when实现动态加载js脚本

    jquery.when方法解决的问题就类似于java中多线程的问题,js发起的多个ajax请求。

    当我们前台需要同时发起多个ajax请求,并且所有ajax都成功返回后,才执行某个操作。

    原始的方式是使用ajax嵌套,也就是在一个ajax的回调函数中发起另一个ajax,但是这样无疑影响效率且容易带来弊端(我之前这么用的时候总是出现以下奇怪的问题,到现在我也没明白什么原因)。而现在使用when方法能轻易的解决这个问题。下面用when方法实现一个简单的动态加载js的方法:

    基础代码:

$.loadJs = function(urls, success, fail) {
    // 参数适配,可以支持string|Array类型的参数
    urls = $.isArray(urls) ? urls : urls.split(/,|;|\s+/)
    var ajaxs = []
    for(var i = 0, l = urls.length; i < l; i++) {
        ajaxs.push($.getScript(urls[i]))
    }
    $.when.apply(this, ajaxs).done(success).fail(fail)
}

    当然,上面的代码存在很多bug,比如js会重复加载问题,重复加载可能引起变量重复初始化从而导致错误发生,改进:

$.loadJs = function(urls, success, fail) {
    // 参数适配,可以支持string|Array类型的参数
    urls = $.isArray(urls) ? urls : urls.split(/,|;|\s+/)
    var ajaxs = []
    for(var i = 0, l = urls.length; i < l; i++) {
        if( !$("script[src='" + urls[i] + "']")[0] ) {
            ajaxs.push($.getScript(urls[i]))
        }
    }
    $.when.apply(this, ajaxs).done(success).fail(fail)
}

    这次,我们在push之前先判断js是否已经加载,是不是就万无一失了呢?不是。这段代码仍然有潜在风险。我们在不同的地方同时调用loadJs来加载同一个脚本,那么就会对同一个脚本发起两个ajax请求,还是会引起冲突,所以我们需要有一个请求池。

$.loadJs = function(urls, success, fail) {
    // 请求池
    var cache = $.loadJS.cache = $.loadJS.cache || {}
    var getDeferred = function(url) {
        if( url in cache) return cache[url]
        return cache[ url ] = $.getScript( url )
    }
    // 参数适配,可以支持string|Array类型的参数
    urls = $.isArray(urls) ? urls : urls.split(/,|;|\s+/)
    var ajaxs = []
    for(var i = 0, l = urls.length; i < l; i++) {
        if( !$("script[src='" + urls[i] + "']")[0] ) {
            ajaxs.push( getDeferred( urls[i] ) )
        }
    }
    $.when.apply(this, ajaxs).done(success).fail(fail)
}
     现在不管何时何地,调用loadJs来加载同一个url的脚本,就会获得同一个ajax延迟对象。

    一个简单的动态加载插件就算完成了。

标签: jquery ajax

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.jsunw.com/?post=29

相关推荐

评论

  1. 2018-06-22 14:28
    一定要多来看看

你肿么看?

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。