Skip to content

Instantly share code, notes, and snippets.

@micahjon
Last active November 5, 2017 12:59
Show Gist options
  • Save micahjon/a4e57e586249dc3833e4 to your computer and use it in GitHub Desktop.
Save micahjon/a4e57e586249dc3833e4 to your computer and use it in GitHub Desktop.
Promise-based Asynchronous Script Loader
/**
* Loads javascript file by url and saves reference to it by name, so it's not loaded again
* @param {string} name Name of js library
* @param {string} url Url to js library
* @return {promise} Resolves when library is loaded
*
* Based on example by Brad Berger: https://bradb.net/blog/promise-based-js-script-loader/
* Extended w/ global variable to keep track of previously loaded scripts.
* Removed support for loading several independent scripts at once via Promise.all()
*
* If you load a js file (e.g. jQuery) w/out this loader, be sure to append this at the end of it:
* gc.scripts.jquery = Promise.resolve();
*/
gc.scripts = {};
gc.loadScript = function(name, url) {
// script has already been loaded (or is in-flight)
if (gc.scripts.hasOwnProperty(name)) {
return gc.scripts[name];
}
// promise resolves when script has been loaded
var p = new Promise(function (resolve, reject) {
var r = false,
h = document.getElementsByTagName("head")[0],
s = document.createElement("script");
s.src = url;
s.async = true;
s.onload = s.onreadystatechange = function () {
if (!r && (!this.readyState || this.readyState == "complete")) {
r = true;
resolve(this);
}
};
s.onerror = s.onabort = reject;
h.appendChild(s);
});
// store record of promise so js file is never loaded twice
gc.scripts[name] = p;
// return promise so it can be used to trigger callback function
return p;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment