Skip to main content

Нескінченний цикл

Коротка відповідь

Якщо у функції є нескінченний цикл, JavaScript ніколи не звільнить стек викликів, і Event Loop зупиниться - жодні інші задачі (таймери, проміси, кліки, перемальовування інтерфейсу) не зможуть виконуватися. У результаті сторінка "зависне".


Приклад

javascript
function infinite() { while (true) { console.log('вічно...'); } } infinite();

Що станеться:

  1. Функція infinite() потрапляє у Call Stack.
  2. Починається виконання циклу while (true) - він ніколи не завершиться.
  3. Рушій ніколи не вийде з функції, а отже:
  • стек ніколи не звільниться,
  • Event Loop не зможе взяти наступну задачу,
  • браузер перестане реагувати (кліки, скрол, навіть DevTools можуть "зависнути").

Чому це відбувається

JavaScript - однопотокова мова. Він може виконувати лише один шматок коду в певний момент часу (той, що перебуває в Call Stack).

Поки функція не завершиться, рушій не перемкнеться на інші задачі - ні на setTimeout, ні на Promise.then.


Приклад з таймером (який ніколи не спрацює)

javascript
setTimeout(() => console.log('Я не виконаюся'), 0); while (true) {} // нескінченний цикл

Пояснення:

  • setTimeout кладе колбек у чергу макрозадач;
  • Але поки while(true) працює, стек не звільняється;
  • Event Loop не може взяти задачу з черги;
  • console.log('Я не виконаюся') ніколи не виконається.

Підсумок

НаслідокОпис
Блокування стекаКод не виходить з функції -> стек не звільняється
Зупинка Event LoopЧерги задач (таймери, проміси) не обробляються
Зависання сторінкиUI не перемальовується, браузер може показати "Сторінка не відповідає"
Немає реакції на подіїКліки, скроли, введення не працюють

Як уникнути блокування

Використовуй асинхронність або розбиття задач:

Варіант 1: setTimeout

javascript
function loop() { console.log('ітерація'); setTimeout(loop, 0); // дає рушію "передихнути" } loop();

Варіант 2: requestAnimationFrame

Підходить для візуальних задач (анімацій):

javascript
function animate() { // малюємо кадр requestAnimationFrame(animate); } animate();

Варіант 3: Web Worker (якщо потрібна важка обчислювальна логіка)

Винести обчислення в окремий потік:

javascript
// worker.js onmessage = e => { while (true) {} // можна робити довго - UI не зависне };

Висновок

ТермінПояснення
Нескінченний цикл у функціїНіколи не виходить із Call Stack
НаслідокEvent Loop блокується, браузер "завмирає"
РішенняДілити роботу на частини (setTimeout, requestAnimationFrame, Web Workers)

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.