Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Async Load JavaScript Files with Callback

I am trying to write an ultra simple solution to load a bunch of JS files asynchronously. I have the following script below so far. However the callback is sometimes called when the scripts aren't actually loaded which causes a variable not found error. If I refresh the page sometimes it just works because I guess the files are coming straight from the cache and thus are there quicker than the callback is called, it's very strange?

var Loader = function () {

}
Loader.prototype = {
    require: function (scripts, callback) {
        this.loadCount      = 0;
        this.totalRequired  = scripts.length;
        this.callback       = callback;

        for (var i = 0; i < scripts.length; i++) {
            this.writeScript(scripts[i]);
        }
    },
    loaded: function (evt) {
        this.loadCount++;

        if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call();
    },
    writeScript: function (src) {
        var self = this;
        var s = document.createElement('script');
        s.type = "text/javascript";
        s.async = true;
        s.src = src;
        s.addEventListener('load', function (e) { self.loaded(e); }, false);
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(s);
    }
}

Is there anyway to test that a JS file is completely loaded, without putting something in the actual JS file itself, because I would like to use the same pattern to load libraries out of my control (GMaps etc).

Invoking code, just before the tag.

var l = new Loader();
l.require([
    "ext2.js",
    "ext1.js"], 
    function() {
        var config = new MSW.Config();
        Refraction.Application().run(MSW.ViewMapper, config);
        console.log('All Scripts Loaded');
    });

Thanks for any help.

like image 537
Gcoop Avatar asked Jun 13 '10 15:06

Gcoop


People also ask

How do I load a JavaScript file asynchronously?

How to load a JavaScript file asynchronously from the server and automatically execute it. The HTML5 attribute async tells the browser to load this script without blocking the page. defer does essentially the same, but works on several older browsers, too.

How do you use asynchronous and defer loading for your CSS and JavaScript files?

The simplest solution is to keep all of your scripts inline at the bottom of the page, that way they don't block the loading of HTML content while they execute. It also avoids the issue of having to asynchronously load each required script.

Should I async or defer jQuery?

For example, if you're using jQuery as well as other scripts that depend on it, you'd use defer on them (jQuery included), making sure to call jQuery before the dependent scripts. A good strategy is to use async when possible, and then defer when async isn't an option.


2 Answers

Just in case you find this useful, I've created an async utility library that would let you write the above code as:

var Loader = function () {}

Loader.prototype = {
    require: function (scripts, callback) {
        async.map(scripts, this.writeScript, callback);
    },
    writeScript: function(src, callback) {
        var s = document.createElement('script');
        s.type = "text/javascript";
        s.src = src;
        s.addEventListener('load', function (e) { callback(null, e); }, false);
        var head = document.getElementsByTagName('head')[0];
        head.appendChild(s);
    }
}

If you're doing lots of asynchronous calls it has some quite powerful features :)

http://caolanmcmahon.com/async.html

like image 91
Caolan Avatar answered Sep 20 '22 05:09

Caolan


What about jQuery....

$.getScript('abc.js'); 

Above code will load the "abc.js" script file asynchronously....

like image 35
Rajesh Shelar Avatar answered Sep 19 '22 05:09

Rajesh Shelar