jQuery:按顺序加载脚本

gre*_*dit 10 ajax jquery asynchronous

我正在尝试使用jQuery动态加载一些脚本:

var scripts = ['script1.js','script2.js','script3.js'];

$.each(scripts , function(i, val) {
     $.getScript(val, function() {
     console.log('loaded '+ val);
});
Run Code Online (Sandbox Code Playgroud)

但有时加载脚本的顺序会发生变化.如何在上一个脚本成功加载后加载每个脚本?

Jas*_*per 17

您可以使用$.getScript()作为递归函数调用的回调函数在前一个加载完成后加载每个.

//setup array of scripts and an index to keep track of where we are in the process
var scripts = ['script1.js','script2.js','script3.js'],
    index   = 0;

//setup a function that loads a single script
function load_script() {

    //make sure the current index is still a part of the array
    if (index < scripts.length) {

        //get the script at the current index
        $.getScript(scripts[index], function () {

            //once the script is loaded, increase the index and attempt to load the next script
            console.log('Loaded: ' + scripts[index]);
            index++;
            load_script();
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

代码中发生的是脚本同时被请求,并且由于它们异步加载,它们以随机顺序返回和执行.

更新

我没有对此进行过测试,但如果脚本是本地托管的,那么您可以尝试以纯文本格式检索它们,然后将所有代码存储在变量中,直到它们全部加载为止,此时您可以按顺序评估脚本:

var scripts   = ['script1.js','script2.js','script3.js'],

    //setup object to store results of AJAX requests
    responses = {};

//create function that evaluates each response in order
function eval_scripts() {
    for (var i = 0, len = scripts.length; i < len; i++) {
        eval(responses[scripts[i]]);
    }
}

$.each(scripts, function (index, value) {
    $.ajax({
        url      : scripts[index],

        //force the dataType to be `text` rather than `script`
        dataType : 'text',
        success  : function (textScript) {

            //add the response to the `responses` object
            responses[value] = textScript;

            //check if the `responses` object has the same length as the `scripts` array,
            //if so then evaluate the scripts
            if (responses.length === scripts.length) { eval_scripts(); }
        },
        error    : function (jqXHR, textStatus, errorThrown) { /*don't forget to handle errors*/ }
    });
});
Run Code Online (Sandbox Code Playgroud)


Fel*_*ing 10

你让使用的事实jqXhr对象由归国$.getScript(和所有其他的Ajax方法)实现了无极接口,因此提供了.pipe()可用于链递延对象:

var deferred = new $.Deferred(),
    pipe = deferred;

$.each(scripts , function(i, val) {
     pipe = pipe.pipe(function() {
         return  $.getScript(val, function() {
             console.log('loaded '+ val);
         });
     });
});

deferred.resolve();
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请查看延迟对象deferred.pipe.

总的来说,使用延迟对象可以提供更大的灵活性,并且可以让您更轻松地添加错误处理程序.