<MyRusakov.ru />

Создание игр на Unreal Engine 5

Создание игр на Unreal Engine 5

Данный курс научит Вас созданию игр на Unreal Engine 5. Курс состоит из 12 модулей, в которых Вы с нуля освоите этот движок и сможете создавать самые разные игры.

В курсе Вы получите всю необходимую теоретическую часть, а также увидите массу практических примеров. Дополнительно, почти к каждому уроку идут упражнения для закрепления материала.

Помимо самого курса Вас ждёт ещё 8 бесплатных ценных Бонусов: «Chaos Destruction», «Разработка 2D-игры», «Динамическая смена дня и ночи», «Создание динамической погоды», «Создание искусственного интеллекта для NPC», «Создание игры под мобильные устройства», «Создание прототипа RPG с открытым миром» и и весь курс «Создание игр на Unreal Engine 4» (актуальный и в 5-й версии), включающий в себя ещё десятки часов видеоуроков.

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Event Loop в JavaScript: микрозадачи и макрозадачи с примерами

Event Loop в JavaScript: микрозадачи и макрозадачи с примерами

Event Loop в JavaScript — базовый механизм, который определяет, когда выполняется ваш код: синхронный, коллбэки, промисы, таймеры и обработчики событий. Понимание очередей микрозадач и макрозадач помогает писать плавные интерфейсы, избегать лагов и уверенно проходить собеседования.

Event Loop JavaScript: микрозадачи и макрозадачи — что это

JavaScript однопоточен: в каждый момент времени исполняется одна операция. Остальные «ждут» своей очереди в специальных очередях задач, которыми управляет Event Loop.

  • Микрозадачи (microtasks): коллбэки Promise.then/catch/finally, queueMicrotask, MutationObserver. Выполняются сразу после текущего стека синхронного кода и до следующей макрозадачи и перерисовки.
  • Макрозадачи (macrotasks): setTimeout, setInterval, обработчики DOM-событий, MessageChannel, сетевые коллбэки и т. п. Выполняются после завершения микрозадач и возможной перерисовки.

Общий цикл: синхронный код → все микрозадачи → возможно рендер → одна макрозадача → снова микрозадачи → рендер → ...

Порядок выполнения: наглядный пример

console.log('A');

setTimeout(() => console.log('B setTimeout'), 0);

Promise.resolve().then(() => console.log('C microtask: Promise.then'));

queueMicrotask(() => console.log('D microtask: queueMicrotask'));

console.log('E');

Вывод будет: A, E, C, D, B. Сначала — синхронные A, E, потом микрозадачи (C, затем D в порядке постановки), и лишь затем макрозадача от setTimeout.

Async/await и микрозадачи

await ставит продолжение функции в очередь микрозадач (через Promise).

async function demo() {
  console.log('1');
  await null; // то же, что await Promise.resolve(null)
  console.log('2');
}

console.log('0');

demo();

console.log('3');

Порядок: 0, 1, 3, 2. После await выполнение demo «уходит» в микрозадачу, которая сработает после завершения текущего синхронного стека.

Практика: как не блокировать интерфейс

Длинные циклы и тяжелые вычисления «замораживают» UI, ведь главный поток занят. Решение — разбивать работу на порции и уступать управление циклу событий, позволяя браузеру отрисовать кадр.

Плохой пример

// Блокирует поток, интерфейс подвисает
for (let i = 0; i < 1e8; i++) {
  // тяжёлая работа
}
console.log('Готово');

Разбиение на чанки + уступаем кадр

// Уступаем отрисовке через requestAnimationFrame
function nextFrame() {
  return new Promise(resolve => requestAnimationFrame(resolve));
}

async function processInChunks(items, chunkSize = 1000) {
  for (let i = 0; i < items.length; i += chunkSize) {
    const chunk = items.slice(i, i + chunkSize);
    // обработка порции
    for (const x of chunk) {
      // ... работа с x
    }
    // уступаем управление, чтобы браузер успел отрисовать кадр
    await nextFrame();
  }
  console.log('Готово без фризов');
}

Почему не microtask для этого? Микрозадачи выполняются до отрисовки. Если вставлять await Promise.resolve() в цикл, вы не дадите браузеру «вдохнуть». Используйте requestAnimationFrame или хотя бы setTimeout(..., 0) для уступки следующей макрозадаче.

Уступка через setTimeout и MessageChannel

// Макрозадача с минимальной задержкой
await new Promise(r => setTimeout(r, 0));

// Или MessageChannel — часто быстрее, чем setTimeout(0)
const ch = new MessageChannel();
ch.port1.onmessage = () => console.log('macrotask via MessageChannel');
ch.port2.postMessage(null);

Частые ошибки и как их исправить

  • Бесконечные микрозадачи «голодают» цикл.
    function spin() {
      Promise.resolve().then(spin); // микрозадача снова ставит микрозадачу
    }
    spin(); // интерфейс перестанет отрисовываться
    

    Исправление — периодически отдавайте управление через макрозадачу:

    function spinSafe() {
      setTimeout(spinSafe, 0); // макрозадача даёт шанс отрисовке и другим задачам
    }
    spinSafe();
    
  • async в forEach не «ждёт» внутри цикла.
    const items = [1,2,3];
    items.forEach(async (x) => {
      await doWork(x);
    });
    console.log('Готово?'); // выведется раньше, чем doWork завершится
    

    Правильно — использовать for...of с await или Promise.all:

    // Последовательно
    for (const x of items) {
      await doWork(x);
    }
    console.log('Готово!');
    
    // Параллельно
    await Promise.all(items.map(doWork));
    console.log('Готово параллельно!');
    
  • Непонимание приоритета: почему Promise быстрее setTimeout?

    Потому что then — микрозадача, которая выполняется до макрозадач. Запомните: «Promises first, timers later».

Короткая шпаргалка по Event Loop

  • Сначала весь синхронный код, затем все микрозадачи, потом рендер и лишь затем следующая макрозадача.
  • Микрозадачи: Promise.then/catch/finally, queueMicrotask, MutationObserver.
  • Макрозадачи: setTimeout, setInterval, MessageChannel, DOM-события, сетевые коллбэки.
  • await продолжает функцию как микрозадачу.
  • Чтобы дать браузеру отрисовать интерфейс — используйте requestAnimationFrame или макрозадачу.
  • Не используйте бесконечные цепочки микрозадач — это «голодание» рендера.

Мини-викторина для собеседования

console.log(1);
setTimeout(() => console.log(2), 0);
Promise.resolve().then(() => console.log(3));
Promise.resolve().then(() => setTimeout(() => console.log(4), 0));
console.log(5);

Ответ: 1, 5, 3, 2, 4. Объяснение: синхронно — 1 и 5, затем микрозадачи — 3, затем макрозадачи в порядке постановки — 2, и потом 4 (таймер, добавленный из микрозадачи).

Небольшое отличие в Node.js

В Node.js есть ещё process.nextTick — спец. очередь, выполняется раньше промисов (ещё «более микро»). Для браузера достаточно помнить базовое правило о микро- и макрозадачах, а в Node — аккуратно использовать nextTick, чтобы не блокировать цикл событий.

Что дальше изучать

Закрепите тему на практике: поэкспериментируйте с разными комбинациями Promise, setTimeout, MessageChannel, попробуйте «распилить» тяжёлую задачу с уступкой кадра. А если хотите пройти структурированный путь от основ до продвинутых тем (включая асинхронность, работу с DOM и проектные практики), рекомендую практический курс «JavaScript с Нуля до Гуру 2.0» — разобраться и прокачаться на реальных задачах.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (http://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: http://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: http://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.