Skip to content
AgileLogics
5 min read

The Event Loop and Concurrency Model

Prerequisites: Async/await

JavaScript runs on a single thread — only one piece of code executes at a time. Long-running operations (a network request, a timer) don't block that thread; instead, they're handed off, and their callback is queued to run later via the event loop.

console.log("1");
setTimeout(() => console.log("2"), 0);
Promise.resolve().then(() => console.log("3"));
console.log("4");

// Output: 1, 4, 3, 2

Even with a 0ms delay, setTimeout's callback runs after the currently-executing code finishes, and Promise callbacks ("microtasks") run before setTimeout callbacks ("macrotasks"). This single-threaded model is why JavaScript never needs Python-style threads/locks for basic async work — but it also means one long, blocking, synchronous computation freezes everything else, including the browser's UI.