-1

I am probably making a rookie mistake.

Goal

I have a script loader.js, where I want to supply a set of javascript files intended to manage component shape, size, position, etc.

The file is like this:

const loadScript = (FILE_URL, async = true, type = "text/javascript") => {
    return new Promise((resolve, reject) => {
        try {
            const scriptEle = document.createElement("script");
            scriptEle.type = type;
            scriptEle.async = async;

            //scriptEle.async = false; // i tried with this line as well.
            scriptEle.defer = true;

            scriptEle.src =FILE_URL;

            scriptEle.addEventListener("load", (ev) => {
                resolve({ status: true });
            });

            scriptEle.addEventListener("error", (ev) => {
                reject({
                    status: false,
                    message: `Failed to load the script ${FILE_URL}`
                });
            });

            document.body.appendChild(scriptEle);
        } catch (error) {
            reject(error);
        }
    });
};





$(document).ready(function () {

    setTimeout(proceed, 1);               // wait for the document to be fully ready.


});




async function proceed() {

    await loadVars();              // Load variable definitions
    await loadComponents();        // load component definitions 
    await make_components();       // and populate them

}


function make_components() {

    switch (monitorType) {         // monitor type should be defined once loadvar executes (and console.log agrees) 

        case 1 :

            addMobileHeader(wfull, hfull * 0.1);
            addMobileHeroBlock(wfull, hfull* 0.7);
            break;

    }

}



function loadVars() {

    loadScript("variables.js").then( data  => {
        console.log("Variables: Script loaded successfully", data);
    })
    .catch( err => {
        console.error(err);
    });

}


function loadComponents() {

    loadScript("components_mobile.js").then( data  => {
        console.log("Components (mobilephone): Script loaded successfully _ mobile", data);
    })
    .catch( err => {
        console.error(err);
    });



    loadScript("components_wide.js").then( data  => {
        console.log("Components (widescreen):Script loaded successfully _ wide", data);

    })
    .catch( err => {
        console.error(err);
    });


}

Problem

Of course, make_components() is triggered before loadVars completes execution.

Attempt to solution

Inspired from this answer,I thought that since variables.js is added first, it will be executed first, before the next (deferred) file, components_mobile.js is loaded and executed.

And only after all that is done, then the make_components function will execute, and will find all the definitions in loadVars file.

I know that I can make a call the next function directly in the .then part, like

loadScript("variables.js").then( data  => {
            console.log("Variables: Script loaded successfully", data);
          //call next function here
        })

But that will create a hell of chained function very hard for me to debug.

Question

Is there a way i can force the JS engine in chrome/ firefox to wait while one script is fully loaded and executed? Thank you.

EDIT : Without third party libraries, if possible please.

7
  • reason you are reinventing requirejs? Commented Sep 1, 2023 at 17:59
  • @epascarello did not know about it. Ill check. Also I want iwithout third party stuff if possible. Commented Sep 1, 2023 at 17:59
  • Dynamic imports have been available for a few years now and are widely supported. Even if you stick to what's strictly available in browsers you're still re-inventing the wheel. Commented Sep 1, 2023 at 18:06
  • 1
    Using your way, requirejs, or import, you are going to have to deal with promises. Commented Sep 1, 2023 at 18:08
  • 1
    Should just be developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Sep 1, 2023 at 18:08

1 Answer 1

1

Your loadVars and loadComponents are implicitly returning undefined, so await loadVars() and await loadComponents() don't actually wait for anything. You'll need to return a promise.

If you prefer .then syntax, do:

function loadVars() {
  // added "return" on the next line
  return loadScript("variables.js")
    .then(data => {
      console.log("Variables: Script loaded successfully", data);
    })
    .catch( err => {
      console.error(err);
    });
}

If you prefer async/await, do:

async function loadVars() {
  try {
    const data = await loadScript("variables.js");
    console.log("Variables: Script loaded successfully", data);
  } catch (err) {
    console.error(err);
  }
}

And make a similar change in loadComponents

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.