1

I have about half a dozen JS class files right now. Instead of putting in a bunch of tags, I used jQuery to load them dynamically--in order--like so:

var classes = ["A","B","C"...];
blah.load = function(callback) {
    for (var i in classes) {
        console.log("Loading "+blah.RootURL+"/"+classes[i]+".js");
        $.ajax({
            async: true,
            url: blah.RootURL+"/"+classes[i]+".js",
            dataType: "script",
            error: function(jqxhr, status, error) {
                console.log("Unable to load "+classes[i]+": "+status+", "+error);
            },
            success: function(data, status, xhr) {
                if (window.tmpLoadCount) {
                    window.tmpLoadCount++;
                } else {
                    window.tmpLoadCount = 1;
                }

                if (window.tmpLoadCount == classes.length) {
                    console.log("Initializing...");
                    callback();
                }
            }
        });
    }
};

Currently I'm using multiple script tags so I can keep working. The problem I had with the jQuery approach was that sometimes, when [re]loading, previous scripts didn't seem to execute (or finish executing) before the next script was loaded, even with async: true. My classes are pretty short and simple. I would see the script load via the "Loading" log, but then later see an error like "Unable to load B: A is not a constructor" (if B inherits from A), which suggests to me that A wasn't fully loaded when the B.prototype=new A(); line was executed.

I found one reference to this online, and that suggested adding a setTimeout() call to give the engine some time, and suggested that this only happened when processing stuff in jQuery's "success" callback...unfortunately I'm not sure how to ensure that everything gets loaded in order in a dynamic way without using the success callback.

Aside from many <script/> tags or minifying (which makes debugging harder) or requiring class changes, does anyone have suggestions on how to cleanly avoid this "race condition"? My current thought, which I don't really like, is to have the final line in each class file add it's class name to a global static property, and have the ajax call use an interval to check that property to determine if it should load the next file...bleh.

3
  • what is ur callback() function doing? Commented Apr 16, 2012 at 15:04
  • You might try looking at a script loader like LABjs or Requirejs. Commented Apr 16, 2012 at 15:04
  • 1
    take a look at requirejs.org Commented Apr 16, 2012 at 15:05

2 Answers 2

3

RequireJS is actually designed for this kind of situation. You should give serious thought to using it. I personally consider this blog post by Aaron Hardy to be a better, shorter, clearer description of what RequireJS is and how to use it than what is actually contained in the their own docs. You might take a few minutes to read through that and I think you'll find it a pretty good solution.

Sign up to request clarification or add additional context in comments.

Comments

0

one thing u can do in present senario is that call the loading of next script only when the present is done. ie in the success function something like this.

function something(i){
    $.ajax({
                async: true,
                url: blah.RootURL+"/"+classes[i]+".js",
                dataType: "script",
                error: function(jqxhr, status, error) {
                    console.log("Unable to load "+classes[i]+": "+status+", "+error);
                },
                success: function(data, status, xhr) {
                    if (window.tmpLoadCount) {
                        window.tmpLoadCount++;
                    } else {
                        window.tmpLoadCount = 1;
                    }
    something(window.tmpLoadCount);
                    if (window.tmpLoadCount == classes.length) {
                        console.log("Initializing...");
                        callback();
                    }
                }
            });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.