Correct me if I'm wrong but in javascript the callback queue is fifo,
stacking the stream first and out first?
Not quite. Async callbacks are processed FIFO in the order they complete their operations, not in the order their operations were started. So, the amount of time the operation takes to complete is very important in determining when the callback gets scheduled. Short operations may complete before long operations, even if they were started later.
It takes time to open a file and start reading it and the setTimeout() takes no time so it occurs first. When you have independent asynchronous operations, you can almost never "know" what order they will occur in because it depends upon the internal timing of the various functions.
The readStream operation gets started before the timer gets started, but the timer finishes before the readStream operation gets its first data just due to the amount of work required internally for the two async operations.
I think that because of the non-blocking nature of nodejs, both
callback are run in "parallel" and setTimeout finishes first and
return (for example a timeout of 1000ms would switch the results.)
Yes, this is correct.
Think of it like this. You have two powerful megaphones and a really good microphone. You set up two targets to point the megaphone at and listen for the returned echo. One target ie very close and one target is very far away. You first blast the megaphone at the very far away target, then immediately blast the megaphone at the near target. In no surprise, you get the echo from the near target first even though you sent its blast after the first one, simply because the echo from the far away target takes a lot longer to traverse all its extra distance and get back to you. The same is true of your readStream. Even though you started it first, it takes a lot longer than a setTimeout(fn, 0) so the setTimeout() finishes first and thus calls its callback first.
If the timing is important to you, then you SHOULD use tools like promises to specifically sequence your async operations or to wait until all necessary results are ready. A good design should not "assume" that one async operation will complete before another unless your code specifically guarantees that by sequencing the operations.