Лекция
setImmediate - это функция, которая используется в среде выполнения JavaScript для запуска колбэков или кода после завершения текущего цикла событий. Она предоставляет возможность выполнения кода в следующем цикле событий без необходимости добавления задачи в очередь макрозадач (macrotask), такой как setTimeout.
Функция, отложенная через setTimeout(..0)
выполнится не ранее следующего «тика» таймера, минимальная частота которого может составлять от 4 до 1000мс. И, конечно же, это произойдет после того, как все текущие изменения будут перерисованы.
Но нужна ли нам эта дополнительная задержка? Как правило, используя setTimeout(func, 0)
, мы хотим перенести выполнение func
на «ближайшее время после текущего кода», и какая-то дополнительная задержка нам не нужна. Если бы была нужна — мы бы ее указали вторым аргументом вместо 0
.
setImmediate(func)
Для того, чтобы поставить функцию в очередь на выполнение без задержки, в Microsoft предложили метод setImmediate(func). Он реализован в IE10.
У setImmediate
единственный аргумент — это функция, выполнение которой нужно запланировать.
В других браузерах setImmediate
нет, но его можно эмулировать, используя, к примеру, методpostMessage, предназначенный для пересылки сообщений от одного окна другому. Детали работы сpostMessage
вы найдете в статье Общение окон с разных доменов: postMessage . Желательно читать ее после освоения темы «События».
Эмуляция setImmediate
с его помощью для всех браузеров, кроме IE<8 (в которых нет postMessage
, так что будет использован setTimeout):
setImmediate(function() { console.log('Этот код выполнится в следующем цикле событий'); }); console.log('Этот код выполнится первым'); // Другие задачи... // Когда цикл событий завершится, выполнится код, переданный в setImmediate
Это позволяет оптимизировать производительность, так как код в setImmediate будет выполнен после завершения текущего цикла событий, что может быть полезно в некоторых асинхронных сценариях. Однако, стоит отметить, что setImmediate не является стандартной функцией в языке JavaScript и поддерживается не во всех средах выполнения. В частности, в браузерах функции setImmediate может не быть, и вместо нее используется setTimeout(fn, 0) для аналогичного эффекта.
Есть и более сложные эмуляции, включая MessageChannel для работы с Web Workers и хитрый метод для поддержки IE6-8: https://github.com/NobleJS/setImmediate. Все они по существу являются «хаками», направленными на то, чтобы обеспечить поддержку setImmediate
в тех браузерах, где его нет.
Чтобы сравнить реальную частоту срабатывания — измерим время на подсчет от 1 до 100 при
setTimeout/setImmediate
:
Когда речь идет о производительности в JavaScript, особенно в браузере, важно помнить, что точные результаты могут зависеть от множества факторов, включая окружение выполнения, загрузку системы и другие факторы.
Однако, для сравнения setTimeout и setImmediate, которая часто используется в среде Node.js, вы можете использовать следующий код:
// Измерение времени выполнения с использованием setTimeout let startTimeout = Date.now(); setTimeout(function () { for (let i = 0; i < 100; i++) { // Просто некоторая работа let result = Math.pow(i, 2); } let endTimeout = Date.now(); console.log('Время выполнения через setTimeout:', endTimeout - startTimeout, 'мс'); }, 0);
// Измерение времени выполнения с использованием setImmediate (в Node.js) let startImmediate = Date.now(); setImmediate(function () { for (let i = 0; i < 100; i++) { // Просто некоторая работа let result = Math.pow(i, 2); } let endImmediate = Date.now(); console.log('Время выполнения через setImmediate:', endImmediate - startImmediate, 'мс'); });
Этот код создает два таймера: один с использованием setTimeout, а другой с использованием setImmediate. Каждый из них выполняет цикл с некоторой "работой". В конце выполнения каждого таймера выводится время, затраченное на выполнение цикла.
Пожалуйста, помните, что setImmediate не является стандартным в браузерной среде, поэтому вы можете использовать setTimeout для аналогичного теста в браузере.
Вы можите запустить код пример выше — и вы увидите реальную разницу во времени между setTimeout(.., 0) и setImmediate. Да, она может быть более в 50, 100 и более раз.
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)