简体   繁体   中英

Wait for JavaScript scripts to load in HTML

I am adding a plugins system to a program and I want the user to be able to include files and raw information. I have a problem, however with loading the scripts. I want to wait for all the scripts to load (I don't know the number of them, however). An example is this:

Plugins.json:

{"include":["script1.json", "script2.json"]}

main file ("pluginsFile" variable is the content of "Plugins.json"):

/*I have a system that lets the user import the plugins file*/
loadedScripts = 0;
if (pluginsFile.include){
    for (i of pluginsFile.include){
        var scriptToAdd = document.createElement("script");
        scriptToAdd.src = pluginsFile.include[i];
        scriptToAdd.addEventListener("load", function(){
            loadedScripts++;
        })
        document.head.appendchild(scriptToAdd);
    }
    while (loadedScripts < document.querySelectorAll("head > script")){//Assume that I only have the scripts I want to add inside the head}
    //After all the scripts loaded
    console.log("loaded");
}

However, when I import the file, the while loop doesn't stop and the tab lags. I want to wait for all the scripts I insert into <head> to be loaded and then continue. I this possible?

With Promises you can wait for each script to be loaded and do something after that.

Create a function that returns a Promise. Put the creation of your script tag, the setting of the src , listening for the load event, and appending the tag to the <head> inside of the promise. Modify the load event that it resolves the promise whenever the load event fires. Resolving tells the promise it is done.

const loadScript = src => new Promise(resolve => {
  const script = document.createElement('script');
  script.src = src;
  script.addEventListener('load', resolve);
  document.head.appendchild(script);
});

Then map over each file source in your pluginsFile.include array and call the function that loads the script inside of the promise. The result should now be an array of promises.

We'll want to wait before continuing until all promises in that array are resolved. We can do this with Promise.all() . The logic that comes after the Promise.all() in the then() method will be executed once all scripts have been loaded.

if (pluginsFile.include.length) {
  const loadingScripts = pluginsFile.include.map(loadScript);
  Promise.all(loadingScripts).then(() => {
    console.log('loaded');
  });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM