{
  "id": 3929154,
  "title": "JavaScript Event Loop: How Does JavaScript Handle Multiple Tasks?",
  "url": "https://urgent.news/2026/08/28/javascript-event-loop-how-does-javascript-handle-multiple-tasks",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-28T08:53:33.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/tanu_priya/javascript-event-loop-how-does-javascript-handle-multiple-tasks-bc0"
  },
  "original_language": "en",
  "account": "JavaScript is commonly referred to as single-threaded, meaning it can execute only one piece of JavaScript code at a time using its main thread. Given this limitation, the question arises as to how JavaScript manages to handle multiple tasks simultaneously. These tasks include API requests, timers, button clicks, user input, file operations, and animations.\n\nConsider the following example:\n```\nconsole.log(\"Start\");\nsetTimeout(() => {\nconsole.log(\"Timer finished\");\n}, 2000);\nconsole.log(\"End\");\n```\nThe output is:\n```\nStart\nEnd\nTimer finished\n```\nWhy is this the case? If JavaScript had to wait for the timer to finish, the output should have been:\n```\nStart\nTimer finished\nEnd\n```\nThe explanation lies in the Event Loop, one of the most crucial concepts in JavaScript. To fully grasp the Event Loop, we need to understand the entire system, which consists of five components:\n\n1. The Call Stack - Execution Arena\nThe Call Stack is where JavaScript executes functions. It acts like a stack of tasks, with the last task added being the first one executed. For instance:\n```\nfunction first() {\nsecond();\n}\nfunction second() {\nconsole.log(\"Hello\");\n}\nfirst();\n```\nThe Call Stack processes the functions step by step:\n```\nCall Stack\nfirst()\n↓\nsecond()\n↓\nconsole.log(\"Hello\")\n```\nAs each function completes, it is removed from the stack. This synchronous execution of code tasks is why JavaScript is typically synchronous by default.\n\n2. Web APIs - Browser's Asynchronous Powerhouse\nThe browser offers powerful features called Web APIs, which handle asynchronous work. Some examples include:\n```\nsetTimeout\nfetch\nDOM events\naddEventListener\nGeolocation\n```\nContinuing with our previous example:\n```\nconsole.log(\"Start\");\nsetTimeout(() => {\nconsole.log(\"Timer finished\");\n}, 2000);\nconsole.log(\"End\");\n```\nHere's what happens:\n- `console.log(\"Start\")` is pushed onto the Call Stack and executed, producing the output \"Start\".\n- The timer is registered with the browser's Web APIs.\n- `console.log(\"End\")` is executed immediately, outputting \"End\".\n\n3. Callback Queue - Waiting for Asynchronous Completion\nOnce an asynchronous operation finishes, its callback can be placed into the Callback Queue, also known as the Task Queue. Web APIs handle this queue. For example:\n```\nsetTimeout(() => {\nconsole.log(\"Timer finished\");\n}, 2000);\n```\nAfter two seconds, the callback `console.log(\"Timer finished\")` is moved into the Callback Queue:\n```\nCallback Queue\n[ console.log(\"Timer finished\") ]\n```\nThe callback cannot execute yet because the Call Stack must be empty.\n\n4. The Event Loop - The Traffic Controller\nThe Event Loop continuously checks whether the Call Stack is empty. If it is, the Event Loop moves waiting work from the queues (Callback Queue and Microtask Queue) back into the Call Stack. The process can be visualized as:\n```\nIs Call Stack Empty?\n┌────────┴────────┐\nNo │ Yes\n▼ │ ▼\nKeep executing Move next task to the Call Stack\n```\nThus, the timer flow becomes:\n```\nsetTimeout(...)\n↓\nWeb APIs\nWait 2 seconds\n↓\nCallback Queue\n↓\nEvent Loop checks Call Stack\n↓\nCallback executes\n```\nThis is why the callback runs after the specified delay.\n\n5. Microtasks - A Secondary Queue\nIn addition to the Callback Queue, there is another queue called the Microtask Queue. Microtasks typically include Promise-related callbacks, such as `.then()`, `.catch()`, `.finally()`, and `queueMicrotask()`. For instance:\n```\nconsole.log(\"Start\");\nPromise.resolve().then(() => {\nconsole.log(\"Promise\");\n});\n```\nThe execution order here is:\n```\nCall Stack\nPromise.resolve()\n↓\nMicrotask Queue\n[ console.log(\"Promise\") ]\n↓\nEvent Loop checks Call Stack\n↓\nCall Stack is empty\n↓\nCallback executes (console.log(\"Start\"))\n↓\nMicrotask Queue processed\n↓\nOutput: Start, Promise\n```\nThe Event Loop handles these microtasks after executing the current stack of tasks (in this case, after \"Start\"). The \"Promise\" output follows the \"Start\" because the microtask queue is processed after the Call Stack is empty.",
  "summary": "JavaScript is often called single-threaded . That means it has one main thread and can execute one piece of JavaScript at a time . So here is the obvious question: If JavaScript can do only one thing at a time, how can it handle all of this? API requests Timers Button clicks User input File operations Animations For example: console . log ( \" Start \" ); setTimeout (() => { console . log ( \" Timer…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}