如何强制按顺序加载脚本数组?

时间:2014-08-06 21:37:15

标签: javascript jquery ajax promise getscript

我正在构建单页Web应用程序,每个“小部件”可能需要一个或多个JavaScript或jQuery库。其中一些脚本可能依赖于其他脚本,但如果我只是创建一系列$.getScript个调用,则它们可能会无序加载。如何强制脚本按顺序加载,即进程在请求脚本2之前等待脚本1下载等?

3 个答案:

答案 0 :(得分:1)

您可以在脚本名称数组上使用reduce方法。

以下是此方法的一个示例:

// Load Script and return promise
function loadScript(script) {
  return $.getScript(script);
}
/**
 * Load list of scripts
 */
function loadScripts(scripts) {
  // Reduce, causes sequenctial order of execution
  return scripts.reduce(function(cur, next){
    // When promise is complete, return next promise (loadScript)
    return cur.then(function(){
      console.log(next);
      // Load the next script and return promise
      return loadScript(next);
    });
  }, $().promise() /* First promise is an empty promise */); 
}

JSBin

或简而言之:

function loadScripts(scripts) {
    return scripts.reduce(function(cur, next){ 
        return cur.then($.getScript.bind($, next));
    }, $.when());
}
loadScripts(["./1.js","./2.js","./3.js").then(function(){ // example usage
    // all done here
});

答案 1 :(得分:0)

此函数接受脚本的URI数组并按顺序加载它们,返回一个jQuery承诺,该承诺将在集合中的最后一个脚本加载时解析。

$.load_scripts_sequentially = function (scripts) {
    var deferred = new $.Deferred();
    var load_script = function (index) {
        var scripts = this;
        if (index > scripts.length - 1) {
            deferred.resolve();
            return;
        }
        $.getScript(scripts[index])
            .done($.proxy(function () {
                load_script.call(this.scripts, this.index + 1);
            }, {scripts: scripts, index: index}))
            .fail($.proxy(function () {
                console && console.error('Failed to load script: ' + this.scripts[this.index], arguments);
                deferred.reject();
            }, {scripts: scripts, index: index}));
    };
    load_script.call(scripts, 0);
    return deferred.promise();
};

使用示例:

$.load_scripts_sequentially(['1.js', '2.js', '3.js']).done(function () {
    console && console.info('All scripts done loading!');
});

答案 2 :(得分:0)

您可以使用异步库来确保按顺序加载所有库。 https://github.com/caolan/async#eachSeries

或者,正如其他一位用户指出的那样,您可以使用require.js