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

Как создать macro task?

2.3 Middle🔥 131 комментариев
#Браузер и сетевые технологии

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

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

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

Как создать macro task?

Macro task (макротаск) в JavaScript — это единица работы, которая выполняется в браузере и обычно занимает больше времени, чем микротаск. Понимание того, как создавать и управлять макротасками, критически важно для оптимизации производительности веб-приложений.

Что такое macro task?

Макротаск — это асинхронная операция, которая помещается в очередь макротасков браузера. Примеры макротасков: setTimeout, setInterval, fetch, события пользователя (клик, ввод),렌더инг.

Macro task выполняется после того, как все микротаски (microtasks) завершены и происходит перерисовка экрана.

Встроенные способы создания макротасков

1. setTimeout — самый распространённый способ

// Создание простого макротаска с задержкой 0 мс
setTimeout(() => {
  console.log('Макротаск выполнен');
}, 0);

// Пример: отложенное выполнение
function deferredTask() {
  setTimeout(() => {
    console.log('Это выполнится после микротасков');
  }, 0);
}

// С параметрами
setTimeout((message) => {
  console.log(message);
}, 1000, 'Привет из макротаска');

2. setInterval — повторяющиеся макротаски

// Каждые 1000 мс создаётся новый макротаск
const intervalId = setInterval(() => {
  console.log('Повторяющийся макротаск');
}, 1000);

// Остановка интервала
clearInterval(intervalId);

3. requestAnimationFrame — для анимаций

// Это технически микротаск, но может быть использовано для управления потоком
requestAnimationFrame(() => {
  console.log('Выполнится перед перерисовкой');
});

4. setImmediate (Node.js и некоторые браузеры)

// В Node.js создаёт макротаск
setImmediate(() => {
  console.log('Макротаск через setImmediate');
});

Порядок выполнения: микротаски vs макротаски

console.log('1. Синхронный код');

Promise.resolve()
  .then(() => console.log('2. Микротаск (Promise)'));

setTimeout(() => {
  console.log('3. Макротаск (setTimeout)');
}, 0);

console.log('4. Синхронный код (конец)');

// Вывод:
// 1. Синхронный код
// 4. Синхронный код (конец)
// 2. Микротаск (Promise)
// 3. Макротаск (setTimeout)

Практические примеры создания макротасков

Пример 1: Деление тяжёлой работы на макротаски

// Обработка большого массива по частям
function processLargeArray(array, callback) {
  let index = 0;

  function processChunk() {
    const chunkSize = 100;
    const end = Math.min(index + chunkSize, array.length);

    for (let i = index; i < end; i++) {
      callback(array[i]);
    }

    index = end;

    if (index < array.length) {
      // Создание нового макротаска для следующей части
      setTimeout(processChunk, 0);
    }
  }

  processChunk();
}

// Использование
const largeArray = Array(1000000).fill(0).map((_, i) => i);
processLargeArray(largeArray, (item) => {
  // Обработка каждого элемента
  console.log(item);
});

Пример 2: Создание макротаска для неблокирующей работы

// Функция для отложенного выполнения без блокировки UI
function scheduleWork(callback) {
  return new Promise((resolve) => {
    setTimeout(() => {
      callback();
      resolve();
    }, 0);
  });
}

// Использование
await scheduleWork(() => {
  // Выполнится как макротаск, не блокируя UI
  console.log('Работа выполнена');
});

Пример 3: Пакетная обработка событий

// Собрать события и обработать их в одном макротаске
class EventBatcher {
  constructor() {
    this.events = [];
    this.scheduled = false;
  }

  add(event) {
    this.events.push(event);

    if (!this.scheduled) {
      this.scheduled = true;
      setTimeout(() => this.flush(), 0);
    }
  }

  flush() {
    const events = this.events;
    this.events = [];
    this.scheduled = false;
    // Обработка всех собранных событий
    this.process(events);
  }

  process(events) {
    console.log('Обработка', events.length, 'событий');
  }
}

const batcher = new EventBatcher();
batcher.add('event1');
batcher.add('event2');
batcher.add('event3');
// Все события обработаны в одном макротаске

Когда использовать макротаски

// ✅ Используй макротаски для:
// 1. Отложенного выполнения (setTimeout(..., 0))
setTimeout(() => {
  // Выполнится после всех микротасков и текущего макротаска
}, 0);

// 2. Неблокирующей обработки больших объёмов данных
setTimeout(() => {
  processHugeDataset();
}, 0);

// 3. Пакетного обновления состояния
setTimeout(() => {
  updateState();
}, 0);

// 4. Откладывание операций для улучшения responsiveness
setTimeout(() => {
  expensiveOperation();
}, 0);

Производительность и оптимизация

// ❌ Неэффективно: много малых макротасков
for (let i = 0; i < 1000; i++) {
  setTimeout(() => processItem(i), 0);
}

// ✅ Эффективно: один макротаск с пакетной обработкой
setTimeout(() => {
  for (let i = 0; i < 1000; i++) {
    processItem(i);
  }
}, 0);

Современные альтернативы

Scheduler API (экспериментально)

// Более современный способ управления приоритетом задач
if ('scheduler' in window) {
  scheduler.postTask(() => {
    console.log('Макротаск через Scheduler API');
  });
}

Лучшие практики

  1. Используй setTimeout(..., 0) для создания макротасков — это наиболее совместимый способ
  2. Избегай глубокой вложенности макротасков — это может привести к проблемам с производительностью
  3. Профилируй код — используй DevTools для анализа длительности макротасков
  4. Предпочитай микротаски, когда возможно — они выполняются быстрее

Вывод: макротаски — это мощный инструмент для управления потоком выполнения в JavaScript, позволяющий создавать отзывчивые и производительные приложения.

Как создать macro task? | PrepBro