Asynchronous Script Loading Callback

script async defer
javascript load script synchronously
javascript load script dynamically callback
jquery load script async
javascript callback
script onload
javascript wait for external script to load
asynchronous loading for css and javascript files

http://jsfiddle.net/JamesKyle/HQDu6/

I've created a short function based on Mathias Bynens Optimization of the Google Analytics asynchronous script that goes as following:

function async(src) {
  var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
  o.src = '//' + src;
  s.parentNode.insertBefore(o, s);
}

This works great and I've already started using it for several different scripts

// Crazy Egg
async('dnn506yrbagrg.cloudfront.net/pages/scripts/XXXXX/XXXXX.js?' + Math.floor(new Date().getTime() / 3600000));

// User Voice
var uvOptions = {};
async('widget.uservoice.com/XXXXX.js');

// Google Analytics
var _gaq = [['_setAccount', 'UA-XXXXX-XX'], ['_setDomainName', 'coachup.com'], ['_trackPageview']];
async('google-analytics.com/ga.js');

// Stripe
async('js.stripe.com/v1');​

The problem comes when I encounter a script that needs to be called after it's loaded:

// Snap Engage
async('snapabug.appspot.com/snapabug.js');
SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');

So I figured I'd turn this into a callback function that would be used as so:

async('snapabug.appspot.com/snapabug.js', function() {
    SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');
});

I did not expect that this would be difficult for me to do but it has turned out that way.

My question is what is the most efficient way to add a callback without overcomplicating the code.

See the jsfiddle: http://jsfiddle.net/JamesKyle/HQDu6/

Thanks RASG for https://stackoverflow.com/a/3211647/982924

Async function with callback:
function async(u, c) {
  var d = document, t = 'script',
      o = d.createElement(t),
      s = d.getElementsByTagName(t)[0];
  o.src = '//' + u;
  if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
  s.parentNode.insertBefore(o, s);
}

Usage:

async('snapabug.appspot.com/snapabug.js', function() {
    SnapABug.init('XXXXX-XXXXX-XXXXX-XXXXX-XXXXX');
});

jsFiddle

Async Script Loader with Callback, var Loader = function () { } Loader.prototype = { require: function (scripts, callback ) { this.loadCount = 0; this.totalRequired = scripts.length; Using a script loader bootstrapper or a self-executing function to asynchronously load scripts solves several performance related issues common to many web sites. They help fight duplicate scripts, reduces the number of scripts loaded when the app is initially loaded and potentially reduce the chance of a Single Point of Failure.

A more recent snippet:

async function loadAsync(src) {
    const script = document.createElement('script');
    script.src = src;
    return new Promise((resolve, reject) => {
        script.onreadystatechange = function () {
            if (script.readyState === 'loaded' || script.readyState === 'complete') {
                script.onreadystatechange = null;
                resolve(true);
            }
        };
        document.getElementsByTagName('head')[0].appendChild(script);
    });
}

utilisation

  loadAsync(`https://....js`).then(_ => {
    //  ... script loaded here
  })

James Kyle's answer doesn't take IE9 into account. Here is a modified version of the code I found in the link proposed in the comments. Modify the var baseUrl so it can find the script accordingly.

//for requiring a script loaded asynchronously.
function loadAsync(src, callback, relative){
    var baseUrl = "/resources/script/";
    var script = document.createElement('script');
    if(relative === true){
        script.src = baseUrl + src;  
    }else{
        script.src = src; 
    }

    if(callback !== null){
        if (script.readyState) { // IE, incl. IE9
            script.onreadystatechange = function() {
                if (script.readyState === "loaded" || script.readyState === "complete") {
                    script.onreadystatechange = null;
                    callback();
                }
            };
        } else {
            script.onload = function() { // Other browsers
                callback();
            };
        }
    }
    document.getElementsByTagName('head')[0].appendChild(script);
}

utilisation:

loadAsync('https://www.gstatic.com/charts/loader.js' , function(){
    chart.loadCharts();
    });
// OR relative path
loadAsync('fastclick.js', null, true);

Asynchronous Script Loading (Example), No point in loading the script on every page if you only use it on one. function asyncLoad(scriptURL,callback) { if(!scriptURL){return;} var� by Stephen Mayeux Understanding Asynchronous JavaScript Callbacks Through Household Chores If you’ve ever done the laundry, you can understand how callbacks work. The other day I read Kevin Kononenko [undefined]’s brilliantly funny and easy-to-understand guide to MVC frameworks. He explains the Model-View-Controller paradigm through ordering drinks at a bar [https://medium.freecodecamp.com

The other answers works well, but aren't super readable or require Promises. Here is my two cents:

function loadScript(src, callback) {
    var script = document.createElement('script');
    script.setAttribute('src', src);
    script.addEventListener('load', callback);
    document.head.appendChild(script);
},

Efficiently load JavaScript with defer and async, src } is loaded` ) ; alert ( _ ) ; // function declared in the loaded script } ) ; That's called a “callback-based” style of asynchronous programming. A function that does something asynchronously should provide a callback argument where we put the function to run after it's complete. Callbacks are frequently used in JavaScript since most operations on asynchronous. Essentially, you’re just passing a function around as a named variable when you use the callback pattern. The callback may or may not be called by the function you pass it to. It could be called immediately, or at some point in the future.

Introduction: callbacks, Async load a script and then fire a callback when loaded. loadScript.js. //this function will work cross-browser for loading scripts asynchronously. reading the script with ajax and adding a <script> tag with the text of the script: works very well on all browsers; you can create async and sync loading with the same function and you can also control very well errors,loading etc.(if you know the basics of ajax you should know how to handle variuous http state) and it's what i recommend.

loadScript. Async load a script and then fire a callback when loaded , Asynchronously, where some scripts can be loaded simultaneously. Loading a script asynchronously has the advantage of not slowing the page� The browser automatically starts loading it and executes when complete. We can use this function like this: // load and execute the script at the given path loadScript('/my/script.js'); The script is executed “asynchronously”, as it starts loading now, but runs later, when the function has already finished.

Synchronous and asynchronous snippet loading, Learn how to asynchronously load a JavaScript file and set up a reliable success handler. //once the script is loaded, run the callback. if (callback){callback()};. Parsing is done before the script is even downloaded, so the page appears to the user way before the previous example. With async, in the head. Here’s how a page loads a script with async, put in the head tag: The script is fetched asynchronously, and when it’s ready the HTML parsing is paused to execute the script, then it’s resumed.

Comments
  • stackoverflow.com/a/3211647/982924 and stackoverflow.com/a/4249346/982924
  • The line o.u = '//' + u; should read o.src = '//' + u; or else it won't load a single byte. Minifying can be tricky at times.
  • s.addEventListener should be o.addEventListener
  • I think this needs more logic to deal with IE8 and before, see for example: aaronpeters.nl/blog/prevent-double-callback-execution-in-IE9
  • I think this solution is more comprehensive and includes a Promise implementation too: stackoverflow.com/questions/7718935/load-scripts-asynchronously
  • terrible variable names
  • Nice work & thanks for the great answer. Just change "doc" in the last line of the function to "document".