Understanding Node.js Event Loop and Async Order

I once had a bug where my callbacks were firing in the wrong order. Spent hours on it. Turns out I had no idea how Node.js actually schedules things. So I read the official docs from start to finish. Here's the whole picture 👇 𝗡𝗼𝗱𝗲.𝗷𝘀 𝗻𝗲𝘃𝗲𝗿 𝘀𝗶𝘁𝘀 𝗮𝗻𝗱 𝘄𝗮𝗶𝘁𝘀. When you read a file, Node doesn't freeze and stare at the disk. It says "I'll come back when it's ready" and goes off handling other things. That's the Event Loop. It's basically a todo list manager that keeps spinning. 𝗧𝗵𝗲 𝗹𝗼𝗼𝗽 𝗵𝗮𝘀 𝟲 𝗽𝗵𝗮𝘀𝗲𝘀, 𝗲𝘃𝗲𝗿𝘆 𝘀𝗶𝗻𝗴𝗹𝗲 𝗿𝗼𝘁𝗮𝘁𝗶𝗼𝗻: 1. Timers⏱️: runs setTimeout / setInterval callbacks 2. Pending🔃: handles I/O errors from last round 3. Idle🏠: internal Node housekeeping (you can't touch this) 4. Poll📁 : the big one, waits for new I/O events. This is where Node spends most of its life 5. Check✅: runs setImmediate callbacks 6. Close🔒:handles things like socket.close() And before moving between ANY of these phases? It drains the microtask queue first (process.nextTick → Promises). 𝗢𝗻𝗲 𝘁𝗵𝗶𝗻𝗴 𝘁𝗵𝗮𝘁 𝘀𝘂𝗿𝗽𝗿𝗶𝘀𝗲𝗱 𝗺𝗲 𝘁𝗵𝗲 𝗺𝗼𝘀𝘁: setTimeout(fn, 0) is NOT actually 0ms. libuv (the engine under Node ie basically a C library.) secretly converts 0 → 1ms. Meanwhile, setImmediate doesn't care about time at all. It just fires after the Poll phase. Every time. No race. No clock. So if you write both in the same script: → Sometimes setTimeout wins → Sometimes setImmediate wins → It depends on how fast your machine booted that loop But inside an I/O callback? setImmediate wins. Always. Guaranteed. 𝗧𝗵𝗲 𝗿𝗲𝗮𝗹 𝘁𝗮𝗸𝗲𝗮𝘄𝗮𝘆: It's one loop, six phases, and a very smart way of never blocking. If you write Node code without knowing this, you're driving with your eyes closed. Have you ever been burned by unexpected async order in Node? Drop it in the comments 👇 #nodejs #javascript #webdevelopment #backend #softwareengineering

  • diagram, schematic

To view or add a comment, sign in

Explore content categories