Excellent question.
JS is single-threaded, which means it cannot run things in parallel. It might be weird for an asynchronous language like JS to run everything sequentially, but that is basically what happens.
JS however provides the illusion of working in parallel by splitting work into tasks and microtasks via the event loop. There's a lot to say about the event loop and I'd recomment this talk by Jake Archibald on the subject, but basically your function loop1
is synchronous and won't be split into tasks, therefore it will run into completion before doing anything else.
You won't be able to have loop1
and loop2
run in parallel, but you can split them into microtasks so that they'll execute like
t=0 loop1's microtask 1
t=1 loop2's microtask 1
t=2 loop1's microtask 2
t=3 loop2's microtask 2
...
A simple way to achieve this would be to await
at each iteration. That'll create an asynchronous promise that resolves as soon as possible, and in the meantime give back the control flow to other awaiting tasks or microtasks.
That is why this runs loop1
then loop2
const loop1 = () => {
for (let i = 0; i < 5; i++) {
console.log(i);
}
}
const loop2 = () => {
for (let i = 5; i < 10; i++) {
console.log(i);
}
}
loop1();
loop2();
but this runs loop1
and loop2
"in parallel"
const loop1 = async () => {
for (let i = 0; i < 5; i++) {
console.log(i);
// defer the remaining work to another microtask
// gives back control to awaiting microtasks, like loop2's remaining work
await null;
}
}
const loop2 = async () => {
for (let i = 5; i < 10; i++) {
console.log(i);
// defer the remaining work to another microtask
// gives back control to awaiting microtasks, like loop1's remaining work
await null;
}
}
loop1();
loop2();