Run two separate functions on DOMContentLoaded

129 Views Asked by At

I have a website which has two files; main.js and loading.js

loading.js waits for DOMContentLoaded, then clears a loading screen cover.

main.js also waits for DOMContentLoaded, but also waits for loading.js to finish its DOMContentLoaded, then executes some more code.

I need to write some code (possibly using Promises?) which allows this to happen.

Here is my code:

loading.js

document.addEventListener('DOMContentLoaded', () => {
    var loadingCover = document.querySelector('#loading-cover');
    loadingCover.style.display = 'none';
});

main.js

document.addEventListener('DOMContentLoaded', () => {
    /* Wait for loading.js */
    console.log("Do stuff");
});

I've done some research with Promises, but I can't wrap my head around how they could work in this situation.

I've tried using a Promise which is resolved inside loading.js. main.js then waits for that Promise to be resolved before executing its own code.

Ideally, this would be the code:

loading.js

const loadingPromise = new Promise();
document.addEventListener('DOMContentLoaded', () => {
    var loadingCover = document.querySelector('#loading-cover');
    loadingCover.style.display = 'none';
    loadingPromise.resolve();
});

main.js

/* Terrible example */
loadingPromise.addEventListener('resolve', () => {
    console.log("Do stuff");
});
1

There are 1 best solutions below

7
Marco On BEST ANSWER

One way to do is by creating a Promise, then saving the resolve function to be later called like this:

//
// createPromise() returns an object containing the promise
// itself and the function to be called in order to resolve
// said promise
//
function createPromise() {
    let ret = {}

    ret.promise = new Promise((resolve) => {
        ret.resolve = resolve
    })

    return ret
}

window.main_promise = createPromise()

document.addEventListener('DOMContentLoaded', () => {
    var loadingCover = document.querySelector('#loading-cover');
    loadingCover.style.display = 'none';

    // add some artificial delay
    setTimeout(window.main_promise.resolve, 1000);
});

In loading.js:

document.addEventListener('DOMContentLoaded', async () => {
    /* Wait for loading.js */
    await window.main_promise.promise;

    console.log("Do stuff");
});

This will block execution of console.log("Do stuff"); until window.main_promise.resolve(); is called somewhere in code.

Of course, main.js needs to be loaded before loading.js in order for this to work.