Last active
November 5, 2017 12:59
-
-
Save micahjon/a4e57e586249dc3833e4 to your computer and use it in GitHub Desktop.
Promise-based Asynchronous Script Loader
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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