If I understood correctly, a function declared with the keyword async should return a promise. In the case of the async3 function, we have 1 billion iterations, which makes the return value take a little longer. Analyzing the code below, what I expected to happen is that, by invoking the sync1 and sync2 function, immediately log on the console and, later, the async3 function log would come. However, what I've noticed is that the sync1 and sync2 functions only log after async3 has ended. Wouldn't the async3 function be supposed to be running on another thread or outside the event loop without blocking the execution of the other functions invoked on the runtime?
function sync1() {
console.log(1);
}
function sync2() {
console.log(2);
}
async function async3() {
let iteration = 0;
let number = 0;
while (iteration <= 1000000000) {
number = iteration;
iteration++;
}
return number;
}
sync1();
sync2();
async3().then((val) => console.log(val));
Can you clarify why it behaves like that. What am I missing?
What I expected:
sync1(); // console logged immediately
sync2(); // console logged immediately
async3().then((val) => console.log(val)); // console logged moments later
What's currently happening:
sync1(); // console logged after async3 is done sync2(); // console logged after async3 is done async3().then((val) => console.log(val)); // console logged after async3 is done
Remember that JavaScript is fundamentally single-threaded.
Although async3
is async, its operations are entirely synchronous, and CPU intensive. The output will only be (visually) printed to the console once the browser has a bit of idle time, but the following block:
while (iteration <= 1000000000) {
number = iteration;
iteration++;
}
leaves the browser no idle time until the above calculations are finished.
For sync1
and sync2
to log immediately, one solution would be to have async3
pause every 100,000 iterations (or something), and await a setTimeout
, thereby giving the browser a chance to do stuff like display stuff to the console, handle other event listeners, render changes, and so on.
Another solution would be to do the computation-heavy async3
function in a worker instead, which is on a separate thread, which won't block the browser's main thread.