Question

I'm currently stuck using several JavaScript libraries that MUST load in a very specific order. Since jQuery's getScript() is asynchronous it starts downloading all of the scripts very quickly and, as they finish, executes them. Since they do not execute in order I get multiple errors coming from the libraries.

Unfortunately I cannot change or modify any of these libraries. What I'm attempting to do is use a method that downloads a JavaScript library and, in the callback, have it call itself until it's finished loading all of the libraries.

This works for the first file. When the second file comes around it loses context inside of the callback and I can't call my recursive method anymore.

Any ideas?

A paired-down version of the code:

function loadFiles (CompletedCallback) {
    var Files = getFiles(); // This is an array of js files to load
    var currentFileIndex = 0;

    function processFile (file) {
        $.getScript(file[currentFileIndex], $.proxy(function () {
            ++currentFileIndex;
            if (currentFileIndex === Files.length) {
                CompletedCallback();
            } else {
                processFile(Files[currentFileIndex]);
            }
        }, this);
    };

    processFile(Files[currentFileIndex]);
};
Was it helpful?

Solution

I'm not sure what's wrong with your code, but here's how I would do that:

function loadOrdered(files, callback) {
   $.getScript(files.shift(), function() {
       files.length
          ? loadOrdered(files, callback)
          : callback();
   });
}

edit, a nicer version:

function loadOrdered(files, callback) {
   $.getScript(files.shift(), files.length
       ? function(){loadOrdered(files, callback);}
       : callback
   );
}

or even nicer, if you don't care about old browsers or implement Function.prototype.bind yourself (with support for binding arguments too, and not just the this context):

function loadOrdered(files, callback) {
   $.getScript(files.shift(), files.length
       ? loadOrdered.bind(null, files, callback)
       : callback
   );
}

OTHER TIPS

You can do sync calls just do this:

$.ajaxSetup({async: false});
$.getScript('library.js');
$.ajaxSetup({async: true});

simple form:

function getScript(url){ $.ajax({url: url, type: 'post', async: false}); }

usage:

getScript(a_url);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top