Лучше написать код, который не зависит от времени немедленных обратных вызовов (например, от микрозадач против макрозадач), но давайте пока отложим это.
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
будет поучительно.