I am building a solution in which multiple Javascript libraries are dynamically loaded at different points in time based on the user's interaction. After the libraries are loaded, the scripts in the library are executed.
For example:
let script1 = '<script src="' + some_script_url_1 +'"></script>';
$("head").append(script1);
let script2 = '<script src="' + some_script_url_2 +'"></script>';
$("head").append(script2);
let script3 = '<script src="' + some_script_url_3 +'"></script>';
$("head").append(script3);
And then some code will execute a function that's defined inside the loaded script:
scriptFunction(); // This function is defined in the dynamically loaded library
The problem is that sometimes the script will not be loaded before the function tries execute. This causes errors like "scriptFunction
not found". How can I wait for each library to load before executing the script? Can this be done with promises?
I am building a solution in which multiple Javascript libraries are dynamically loaded at different points in time based on the user's interaction. After the libraries are loaded, the scripts in the library are executed.
For example:
let script1 = '<script src="' + some_script_url_1 +'"></script>';
$("head").append(script1);
let script2 = '<script src="' + some_script_url_2 +'"></script>';
$("head").append(script2);
let script3 = '<script src="' + some_script_url_3 +'"></script>';
$("head").append(script3);
And then some code will execute a function that's defined inside the loaded script:
scriptFunction(); // This function is defined in the dynamically loaded library
The problem is that sometimes the script will not be loaded before the function tries execute. This causes errors like "scriptFunction
not found". How can I wait for each library to load before executing the script? Can this be done with promises?
- Scripts loaded as you're loading them fire a "load" event when loading is plete, so you can wait for that. – Pointy Commented Aug 20, 2022 at 13:01
- @Pointy The reason why I am looking for a promise route is because I do a Promise.all() where I can wait for all the scripts. – Devin Dixon Commented Aug 20, 2022 at 13:24
-
Sure, well you can wrap the
<script>
imports with a function that returns a Promise that is resolved within a "load" handler. Then any call to a function from within a particular script can use that Promise and put the code in a.then()
handler. – Pointy Commented Aug 20, 2022 at 13:29 - See the answer on how to load scripts in order in this topic Trying to fire the onload event on script tag – Andrew Elans Commented Jul 13, 2023 at 21:01
1 Answer
Reset to default 13Here is a function that returns a promise that resolves when a script has loaded:
function loadScript(src) {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.onload = resolve;
script.onerror = reject;
script.setAttribute("src", src);
document.head.appendChild(script);
});
}
const urls = [
"https://cdnjs.cloudflare./ajax/libs/jquery/3.3.1/jquery.min.js",
"https://cdnjs.cloudflare./ajax/libs/luxon/3.0.1/luxon.min.js"
];
Promise.all(urls.map(loadScript)).then(ready,
err => console.log("Error loading", err.target.src));
function ready() {
console.log("all loaded");
console.log($.fn.jquery);
console.log(luxon.DateTime.now().toString());
}