Лучше написать код, который не зависит от времени немедленных обратных вызовов (например, от микрозадач против макрозадач), но давайте пока отложим это.
setTimeout
ставит в очередь макрозадачу, которая, как минимум, ожидает запуска, пока не завершатся все микрозадачи (и микрозадачи, которые они порождают). Вот пример:
console.log('Macrotask queued');
setTimeout(function() {
console.log('Macrotask running');
});
Promise.resolve()
.then(function() {
console.log('Microtask running');
});
console.log('Microtask queued');
console.log('Last line of script');
Поведение a .then
для разрешенного Promise принципиально отличается от поведения немедленного setTimeout
обратного вызова - Promise .then
будет запущен первым, даже если setTimeout
сначала был поставлен в очередь. Но только современные браузеры поддерживают Promises. Как специальные функции микрозадачи могут быть правильно заполнены, если Promise
их не существует?
Если вы попытаетесь имитировать .then
микрозадачу с помощью setTimeout
, вы будете ставить в очередь макрозадачу, а не микрозадачу, поэтому плохо заполненный .then
не запустится в нужное время, если макрозадача уже поставлена в очередь.
Есть решение, использующее MutationObserver
, но оно выглядит некрасиво и не для чего MutationObserver
. Кроме того, MutationObserver
не поддерживается в IE10 и более ранних версиях. Если кто-то хочет поставить микрозадачу в очередь в среде, которая изначально не поддерживает обещания, есть ли лучшие альтернативы?
(На самом деле я не пытаюсь поддерживать IE10 - это всего лишь теоретическое упражнение о том, как микротрубы можно ставить в очередь без обещаний)
schedule.js
будет поучительно.Ответы:
Если мы говорим об IE, вы можете использовать
setImmediate
https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
setImmediate
поддерживается на IE10. Итак, плюс одна версия IE.И, если вы заинтересованы, плюс Node.js.
Существуют и другие возможные заполнения, вот несколько реализаций: https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (эта упоминается в MDN) https://github.com/taylorhakes/ setAsap / blob / master / setAsap.js (более простой)
И как почти все полифиллы, они тоже безобразны.
Но в любом случае, вот пример по своей сути (с использованием postMessage), и я думаю, что он наименее уродлив из всех (но также не является настоящим полифилом)
источник
Я видел, что в
mutationObserver
обратных вызовах используются микрозадачи, и, к счастью, IE11 поддерживает их, поэтому у меня возникла идея поставить микрозадачу в очередь в IE11, сохранив обратный вызов, а затем сразу же вызвав наблюдателя, изменив элемент:Вы можете открыть IE11 и увидеть, как работает выше, но код выглядит странно.
источник