💥 A Subtle Runtime Behavior Every JavaScript Developer Should Know
This is a behavior of the JavaScript runtime, and I’m going to explain how it works using an example. Let’s see why JavaScript’s single threaded nature can cause unexpected timing delays.
When we call something like,
setTimeout(() => console.log("Timeout done!"), 100);
👉 here’s what actually happens under the hood,
1. The core engine (like V8 in Chrome) executes our JavaScript code line by line in the Call Stack.
2. Once the thread reaches it, function immediately gets moved to the Web API, and the timer starts counting (100 ms). Meanwhile, the main thread continues executing the rest of your code line by line (synchronously).
3. When the 100ms timer finishes, the callback is moved to the Callback Queue (Task Queue).
👉 Here’s the important part:
That callback does NOT go into the Microtask Queue because it’s a macro task. The Microtask Queue is reserved for things like Promises and queueMicrotask(), which have higher priority.
👉 Here’s where it gets interesting:
Even though your timer meets 100ms, the callback cannot run immediately.
The Event Loop will only pick tasks from the Callback Queue when two conditions are satisfied,
** One is the Call Stack is empty
** Second one is Microtask Queue is empty
Which mean our code still has functions running in the Call stack or multiple pending Promises in the Microtask Queue, your setTimeout callback must wait, even if the timer already expired.
💥 This is the limitation of single-threaded JavaScript.
Even though the timer is ready, JavaScript cannot interrupt other running code or microtasks. So our console log that was supposed to run after 100ms might execute after 200ms, 300ms, or even later, depending on how busy the thread is.
👉 Key takeaway:
** setTimeout guarantees a minimum delay, not an exact execution time.
** The Event Loop gives priority to the Microtask Queue first, then the Callback Queue.
** This is not a bug. it’s just how the JavaScript run time behaves.
#JavaScript #WebDevelopment #Frontend #EventLoop #AsyncJS #ProgrammingInsights #SingleThreaded #CodingTips #JavaScriptRuntime
Actually, for UI, in most cases using composition of defined components (like first example) is better approach than building them from an array (second example). In real world, layout would be more complicated (multiple sections, some buttons are bigger than others) and different types of buttons will have slightly different design (for example, operations vs numbers etc.). With composition, you will have button components (with different properties or of different types) organized inside of some grid container. With array of configuration objects (simple string per button will not be enough) and complicated rendering logic in a loop you will end up with quite ugly code.