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