Reputation: 5662
I am building a single-page web application and each "widget" may require one or more JavaScript or jQuery libraries. Some of those scripts may depend on other scripts, but if I just create a series of $.getScript
calls, they may load out of order. How can I force that the scripts are loaded in order, i.e. that the process waits for script 1 to download before requesting script 2, etc.?
Upvotes: 0
Views: 1264
Reputation: 396
You could use the reduce
method on the array of script names.
Here is an example of this approach:
// 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)
Or in short:
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
});
Upvotes: 2
Reputation: 684
You can use the async library to ensure all the libraries are loaded in order. https://github.com/caolan/async#eachSeries
Alternatively, as one other user pointed out, you can use require.js
Upvotes: 0
Reputation: 5662
This function accepts an array of URIs to scripts and loads them in order, returning a jQuery promise that will resolve when the last script in the set has loaded.
$.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();
};
Example usage:
$.load_scripts_sequentially(['1.js', '2.js', '3.js']).done(function () {
console && console.info('All scripts done loading!');
});
Upvotes: 0