Suggest an editImprove this articleRefine the answer for “Infinite loop”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**An infinite loop inside a function means the function never returns, so the call stack is never released. The event loop cannot pick up the next task from the queue, so timers, promise callbacks and click handlers never fire, and the browser stops repainting the interface. The page freezes, and eventually the browser shows a message such as "Page is not responding".** ```javascript setTimeout(() => console.log('I will never run'), 0); while (true) {} // the stack is never released ``` **Key point:** JavaScript is single threaded, so a loop that never ends blocks not one task but the whole application.Shown above the full answer for quick recall.Answer (EN)Image**If a function contains an infinite loop, JavaScript will never release the call stack and the event loop will stop: no other task, neither timers, nor promises, nor clicks, nor interface repaints, will be able to run.** To the user this looks like a page that has completely frozen. ## Theory ### TL;DR - An infinite loop keeps the function from returning, so it stays in the call stack forever. - While the stack is busy, the event loop cannot take a new task from the queue. - Neither `setTimeout`, nor `Promise.then`, nor event handlers will fire. - The browser stops repainting the UI and eventually offers to close the tab. - The fix: split work into chunks (`setTimeout`, `requestAnimationFrame`) or move computation into a Web Worker. ### Quick example ```javascript function infinite() { while (true) { console.log('forever...'); } } infinite(); ``` ### What happens step by step 1. The function `infinite()` is pushed onto the **call stack**. 2. The `while (true)` loop starts and **never finishes**. 3. The engine **never leaves** the function, which means: - the stack is **never released**, - the event loop **cannot take the next task**, - the browser **stops responding** to clicks and scrolling, and sometimes even DevTools freezes. ### Why this happens JavaScript is a **single threaded language**. At any moment it can execute **only one piece of code**, the one currently in the **call stack**. Until the function returns, the engine **will not switch** to other tasks: not to `setTimeout`, not to `Promise.then`. The task queue simply piles up and waits for a free stack that will never come. ### A timer that never fires ```javascript setTimeout(() => console.log('I will not run'), 0); while (true) {} // infinite loop ``` Explanation: - `setTimeout` puts the callback into the **macrotask queue**; - while `while (true)` runs, the **stack is not released**; - the event loop cannot pull the task out of the queue; - `console.log('I will not run')` **never executes**. ### Consequences | Consequence | Description | | --- | --- | | **Stack is blocked** | The code never leaves the function, so the stack is not released | | **Event loop stops** | Task queues (timers, promises) are not processed | | **Page freezes** | The UI is not repainted, the browser may show "Page is not responding" | | **No reaction to events** | Clicks, scrolling and typing do not work | ### How to avoid blocking Use asynchrony, or split the task into chunks. Option 1: `setTimeout` ```javascript function loop() { console.log('iteration'); setTimeout(loop, 0); // lets the engine breathe between iterations } loop(); ``` Option 2: `requestAnimationFrame`, a good fit for visual work and animations: ```javascript function animate() { // draw a frame requestAnimationFrame(animate); } animate(); ``` Option 3: a Web Worker, when you need heavy computation. Move it to a separate thread: ```javascript // worker.js onmessage = e => { while (true) {} // can run long, the UI stays responsive }; ``` ### Summary | Term | Explanation | | --- | --- | | **Infinite loop in a function** | Never leaves the call stack | | **Consequence** | The event loop is blocked, the browser freezes | | **Solution** | Split work into chunks (`setTimeout`, `requestAnimationFrame`, Web Workers) | ### Common mistakes - Thinking that `setTimeout(fn, 0)` will "interrupt" the loop. The callback only joins the queue and runs after the stack is free. - Assuming promises have priority over blocking code. Microtasks also wait for a free stack. - Moving a heavy loop into an `async` function and calling that asynchrony. An `async` function without an `await` on a real asynchronous operation runs synchronously and blocks the thread just the same. - Writing an exit condition that never becomes false, for example forgetting to increment the counter or mutating a copy instead of the variable itself. - Using infinite recursion instead of a loop and expecting a freeze: there you get a fast `RangeError: Maximum call stack size exceeded` instead.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.