← Назад к вопросам

Вызывается ли setTimeout синхронно

2.0 Middle🔥 101 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Является ли setTimeout синхронным или асинхронным

Это один из ключевых концептов JavaScript, который часто путают новички. Ответ: setTimeout вызывается синхронно, но callback выполняется асинхронно.

Как работает setTimeout

Когда вы вызываете setTimeout, сама функция выполняется синхронно - она регистрирует callback в очереди. Но сам callback выполняется позже, асинхронно.

// Пример: синхронный вызов, асинхронное выполнение
console.log('1. До setTimeout');

setTimeout(() => {
  console.log('2. Внутри setTimeout');
}, 0);

console.log('3. После setTimeout');

// Вывод:
// 1. До setTimeout
// 3. После setTimeout
// 2. Внутри setTimeout

// Даже с задержкой 0ms, callback выполняется ПОСЛЕ текущего кода

Почему это происходит: Event Loop

JavaScript использует Event Loop для управления выполнением кода. Процесс выглядит так:

// Симуляция Event Loop

// 1. CALL STACK (текущий код)
console.log('Start'); // выполняется сразу

setTimeout(() => {
  console.log('Callback'); // идет в WEB API
}, 1000);

console.log('End'); // выполняется сразу

// 2. WEB API (браузерные API)
// setTimeout регистрируется здесь и считает 1 секунду

// 3. CALLBACK QUEUE (очередь обратных вызовов)
// Когда таймер истекает, callback переходит сюда

// 4. Event Loop проверяет:
// - Если Call Stack пуст
// - Если есть что-то в Callback Queue
// - Переносит callback в Call Stack для выполнения

// Вывод:
// Start
// End
// Callback (после 1 секунды)

Подробное объяснение с диаграммой

// Пример с несколькими setTimeout

console.log('1');

setTimeout(() => {
  console.log('2');
}, 0);

setTimeout(() => {
  console.log('3');
}, 100);

console.log('4');

// Вывод:
// 1 (Call Stack)
// 4 (Call Stack)
// 2 (первый setTimeout с 0ms - выполнился после Stack очиститься)
// 3 (второй setTimeout с 100ms - выполнился позже)

Синхронное vs Асинхронное выполнение

Что синхронно:

  • Сам вызов setTimeout() - функция регистрируется
  • Возвращается ID таймера
  • Код выполняется по порядку
const timerId = setTimeout(() => {
  console.log('Callback');
}, 1000);

console.log('timerId:', timerId); // выведет ID сразу

Что асинхронно:

  • Выполнение callback функции - происходит позже
  • Когда это произойдет, зависит от Event Loop
setTimeout(() => {
  console.log('Это выполнится позже');
}, 5000);

// Код продолжает выполняться, не ждет 5 секунд
console.log('Это выполнится сейчас');

Важные различия

// СИНХРОННЫЙ КОД
function syncFunction() {
  console.log('Начало');
  for (let i = 0; i < 1000000000; i++) {} // долгое вычисление
  console.log('Конец');
}

syncFunction();
// Программа ждет, пока все выполнится

// АСИНХРОННЫЙ КОД
function asyncFunction() {
  console.log('Начало');
  
  setTimeout(() => {
    for (let i = 0; i < 1000000000; i++) {}
    console.log('Конец');
  }, 0);
  
  console.log('Вторая строка');
}

asyncFunction();
// Вывод:
// Начало
// Вторая строка
// (потом долгое вычисление)
// Конец

Практические примеры

Проблема: ожидание DOM обновления

// Без setTimeout - DOM не успел обновиться
const element = document.querySelector('.box');
element.style.background = 'red';
console.log(element.offsetHeight); // может быть старое значение

// С setTimeout - даем браузеру время на reflow
const element = document.querySelector('.box');
element.style.background = 'red';

setTimeout(() => {
  console.log(element.offsetHeight); // правильное значение
}, 0);

Решение: батчинг обновлений

// Множество операций, каждая в setTimeout
for (let i = 0; i < 1000; i++) {
  setTimeout(() => {
    processItem(i);
  }, 0);
}
// Это засоряет очередь callbacks

// Лучше: обработать всё сразу
for (let i = 0; i < 1000; i++) {
  processItem(i);
}
// Или если нужна асинхронность, использовать requestAnimationFrame
function processBatch() {
  const items = getAllItems();
  items.forEach(item => {
    requestAnimationFrame(() => {
      processItem(item);
    });
  });
}

Вывод

setTimeout синхронен по вызову, асинхронен по выполнению callback. Это ключевое различие. Сама функция выполняется немедленно и регистрирует таймер, но callback будет выполнен позже, когда Event Loop получит контроль над выполнением. Понимание этого критично для работы с асинхронным кодом в JavaScript.

Вызывается ли setTimeout синхронно | PrepBro