0

I am building a solution in which multiple Javascript libraries are dynamically loaded onto the screen 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 class="'+script_class+'" id="' + script_id + '" type="text/javascript" src="' + some_script_url +'"></script>';
    
     $("head").append(script1);

let script2 = '<script class="'+script_class+'" id="' + script_id + '" type="text/javascript" src="' + some_script_url +'"></script>';
    
     $("head").append(script2);

let script3 = '<script class="'+script_class+'" id="' + script_id + '" type="text/javascript" src="' + some_script_url +'"></script>';
    
     $("head").append(script3);

And then a function will execute a function inside the script:

function doSomething() {
      scriptFunction();
}

doSomething();

The problem is sometimes the script will not fully be loaded before the function tries execute. This causes error likes "scriptFunction not found". How can I wait for each libraries to load before executing the scripting? Can this be done with promises?

Devin Dixon
  • 11,553
  • 24
  • 86
  • 167
  • Scripts loaded as you're loading them fire a "load" event when loading is complete, so you can wait for that. – Pointy Aug 20 '22 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 Aug 20 '22 at 13:24
  • Sure, well you can wrap the ` – Pointy Aug 20 '22 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](https://stackoverflow.com/a/76680818/17045797) – Andrew Elans Jul 13 '23 at 21:01

1 Answers1

4

Here is a function that returns a promise that resolves when a script has loaded:

function loadScript(src) {
    return new Promise(resolve => {
        const script = document.createElement("script");
        script.setAttribute("async", "");
        script.onload = resolve;
        script.setAttribute("src", src);
        document.head.appendChild(script);
    });
}

const urls = [
    "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js",
    "https://cdnjs.cloudflare.com/ajax/libs/luxon/3.0.1/luxon.min.js"
];

Promise.all(urls.map(loadScript)).then(ready);

function ready() {
    console.log("all loaded");
    console.log($.fn.jquery);
    console.log(luxon.DateTime.now().toString());
}
trincot
  • 317,000
  • 35
  • 244
  • 286