SYNOPSIS:
In Node.js event queues, and code like "new Promise((r) => setTimeout(r, t));", is the setTimeout() evaluated NOW, in the microqueue for Promise resolves, or where?
DETAILS:
I'm reading through Distributed Systems with Node.js (Thomas Hunter II, O'Reilly, 3rd release of First Edition). It tells me that Node.js goes thru each queue in turn:
- Poll: for most things, including I/O callbacks
- Check: for setImmediate callbacks
- Close: when closing connections
- Timers: when setTimeout and setInterval resolve
- Pending: special system events
There are also two microqueues evaluated after each queue is empty, one for promises and one for nextTick().
On the book's p.13 he has an example where an await calls a function that returns "new Promise((r) => setTimeout(r, t));". The book code is:
const sleep_st = (t) => new Promise((r) => setTimeout(r, t));
const sleep_im = () => new Promise((r) => setImmediate(r));
(async () => {
setImmediate(() => console.log(1));
console.log(2);
await sleep_st(0);
setImmediate(() => console.log(3));
console.log(4);
That is,
setImmediate(() => console.log(1));
console.log(2);
Promise.resolve().then(() => setTimeout(() => {
setImmediate(() => console.log(3));
console.log(4);
This is what I think is going on:
The program starts with a task in the Poll queue, the p.13 code. It starts running.
The Check queue gets a task and the "2" printed to the console.
The "await sleep_st(0)" will have called setTimeout, which puts a task on the Timer queue. Since the timeout is zero, by the time we access the Timer queue there will be work to do. The sleep_st(0) returns a Promise.
This ends the work of the Poll queue.
Now the result micro queue starts. My code resumes executing. This should start with setImmediate() and console.log(4).
This means that the output to the console is "2 4". However, the book says the proper sequence is "2 1 4 3". That is, the event queue for Check, and perhaps Timer, gets involved.
What, then, happens in the promise result microqueue?
Promise.resolve().then(() => setTimeout(() => {. Did you meansleep_st(0).then(() => {in that line?