You can't. You need to stop thinking in loops but start thinking in event loop instead.
There are two functions that can schedule functions to run in the future that can be used for this: setTimeout()
and setInterval()
. Note that in Node.js there is also setImmediate()
but I suggest you avoid using it until you really know what you are doing because setImmediate()
has to potential to block I/O.
Note that neither setTimeout()
not setImmediate()
are Promise aware.
The minimal code example that does what you want would be something like:
const test = () => {
setInterval(() => {
console.log('test1')
},
10 // execute the above code every 10ms
)
setInterval(() => {
console.log('test2')
},
10 // execute the above code every 10ms
)
}
test();
Or if you really want to run the two pieces of code as fast as possible you can pass 0
as the timeout. It won't run every 0ms but just as fast as the interpreter can. The minimal interval differs depending on OS and how busy your CPU is. For example Windows can run setInterval()
down to every 1ms while Linux typically won't run any faster than 10ms. This is down to how fast the OS tick
is (or jiffy
in Linux terminology). Linux is a server oriented OS so sets its tick
bigger to give it higher throughput (each process gets the CPU for longer thus can finish long tasks faster) while Windows is a UI oriented (some would say game oriented) OS so sets its tick
smaller for smoother UI experience.
To get something closer to the style of code you want you can use a promisified setTimeout()
and await it:
function delay (x) {
return new Promise((done, fail) => setTimeout(done,x));
}
const test = async () => {
let a = async (res) => {
while (true) {
console.log('test1')
await delay(0) // this allows the function to be async
}
}
let b = async (res) => {
while (true) {
console.log('test2')
await delay(0) // this allows the function to be async
}
}
a();
b();
}
test();
However, this is no longer the minimal possible working code, though not by much.
Note: After writing the promisified example above it suddenly reminded me of the programming style on early cooperative multitasking OSes. I think Windows3.1 did this though I never wrote anything on it. It reminds me of MacOS Classic. You had to periodically call the WaitNextEvent()
function to pass control of the CPU back to the OS so that the OS can run other programs. If you forgot to do that (or your program gets stuck in a long loop with no WaitNextEvent()
call) your entire computer would freeze. This is exactly what you are experiencing with node where the entire javascript engine "freezes" and executes only one loop while ignoring other code.