I have a module with an asynchronous function init() which is invoked multiple times. However, I only want the effect of the init() function to trigger once and any subsequent calls should just wait for that initial promise to resolve.
Here is my current code. The error in this example is that the second time the init() function is called, it is immediately resolved since the script tag already exists. I would like to wait for the onload callback from the script created on first init() invocation.
let scriptExists = false;
// This function should only be called once
// Returns a mock script that calls onload after 1000ms
function addScript() {
const mockScript = {
onload: () => {}
};
setTimeout(() => mockScript.onload(), 1000);
return mockScript;
}
// Add script and wait for it to load
function init() {
return new Promise((resolve) => {
if (!scriptExists) {
const script = addScript();
scriptExists = true;
script.onload = resolve;
} else {
// TODO: This should only resolve if the script has loaded
resolve();
}
});
}
// Wait for the script to load, then add message
async function doSomethingNice() {
await init();
console.log("nocie");
}
// Wait for the script to load, then add message
async function doSomethingElse() {
await init();
console.log("something else");
}
doSomethingNice();
doSomethingElse();
https://codesandbox.io/s/modest-cohen-9k4bf?file=/src/index.js