Reputation: 1
I have the following code and based on the code I would assume the order of operations would be:
However that is not what happens. Nothing gets displayed/updated in the browser until after the sleep command finishes. In the console "SLEEP start" gets logged before "ONE start".
I've tried enabling async when I call loadScript, I've moved the sleep command inside of two.js. Nothing changes. What am I missing here? How would I change my code to achieve the correct download AND execution?
Here is my code:
html:
<!doctype html>
<html lang="en">
<body>
<div id="div1" style="background-color: orange;">
</div>
<script>
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
//console.log('sleep is executing');
} while (currentDate - date < milliseconds);
}
function loadScript(src, async_enabled = async_enabled) {
let script = document.createElement('script');
script.src = src;
script.async = async_enabled;
document.body.append(script);
}
loadScript("one.js", async_enabled = false);
console.log('SLEEP start');
sleep(8000);
console.log('SLEEP stop');
loadScript("two.js", async_enabled = false);
loadScript("three.js", async_enabled = false);
</script>
</body>
</html>
one.js:
console.log('ONE start');
let one = document.getElementById('div1');
let p1 = document.createElement('p');
p1.innerHTML = 'One';
one.appendChild(p1);
console.log('ONE stop');
two.js:
console.log('TWO start');
let two = document.getElementById('div1');
let p2 = document.createElement('p');
p2.innerHTML = 'Two';
two.appendChild(p2);
console.log('TWO stop');
three.js:
console.log('THREE start');
let three = document.getElementById('div1');
let p3 = document.createElement('p');
p3.innerHTML = 'Three';
three.appendChild(p3);
console.log('THREE stop');
Update I'm just using the sleep command to help me understand how js scripts are loaded and executed (the order). I am not really wanting to use a sleep command in my code. I changed my html to this:
<!doctype html>
<html lang="en">
<body>
<div id="div1" style="background-color: orange;">
</div>
<script>
function sleep(milliseconds) {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
//console.log('sleep is executing');
} while (currentDate - date < milliseconds);
}
function loadScript(src, async_enabled = async_enabled) {
let script = document.createElement('script');
script.src = src;
script.async = async_enabled;
document.body.append(script);
}
loadScript("one.js", async_enabled = false);
</script>
</body>
</html>
Changed one.js to this:
console.log('ONE start');
let one = document.getElementById('div1');
let p1 = document.createElement('p');
p1.innerHTML = 'One';
one.appendChild(p1);
console.log('ONE stop');
loadScript("two.js", async_enabled = false);
And changed two.js to this:
console.log('TWO start');
sleep(5000);
let two = document.getElementById('div1');
let p2 = document.createElement('p');
p2.innerHTML = 'Two';
two.appendChild(p2);
console.log('TWO stop');
I'm still getting the same result. I know I should be understanding why this is happening, but I'm not getting it yet. So how could I change the code to make what happens in one.js display immediately in the browser?
Upvotes: 0
Views: 46
Reputation: 308001
Your sleep
is a busy-sleep, that's a bad idea for various reasons. Especially in JavaScript in a browser, where everything is effectively running single-threaded. This means that while your code is "sleep"-ing, nothing else involving JavaScript will execute.
Your loadScript
method appends a new element to the DOM, that happens instantly. Executing the new script can not start before the current JavaScript run is completed, that's why all the scripts loaded via loadScript
will only start running after your sleep.
The correct approach to fixing this is to embrace the event-driven nature of JavaScript in the browser and not to try to "keep stuff running" with a busy loop.
If you want to "sleep" you simply schedule the new code to run for later and return from the call.
This will incidentally also free up the JavaScript event loop to handle stuff like loading other scripts.
Upvotes: 1