Отсрочка выполнения функций, например, при обработке пользовательских событий, является распространенным шаблоном в JavaScript (см., например, здесь). Раньше единственным способом сделать это было использование setTimeout(myFunc,0)
, однако с обещаниями теперь есть альтернатива: Promise.resolve().then(myFunc)
.
Я предполагал, что они будут делать примерно одно и то же, но, работая над библиотекой, включающей пользовательские события, я подумал, что узнаю, есть ли разница, поэтому я поместил следующий блок в узел:
var logfn=function(v){return function(){console.log(v)}};
setTimeout(logfn(1),0);
Promise.resolve().then(logfn(2));
logfn(3)();
Я ожидал увидеть на консоли 3, 1, 2, но вместо этого я увидел 3, 2, 1. Другими словами, обещание НЕ эквивалентно использованию setTimeout и сначала выходит из блоков. По крайней мере, в Node.
Я повторил тест в Chrome и Firefox с тем же результатом, однако в Edge он получился как 3, 1, 2. Я также ожидаю, что неродные библиотеки промисов будут использовать setTimeout под капотом, поэтому результат будет таким же, как у Edge.
Что определяет порядок разрешения этих вызовов? Какая модель используется этими различными средами для определения порядка выполнения? Представляет ли что-либо из вышеперечисленного стандартное или нестандартное поведение?
PS Я определенно не предлагаю полагаться на что-либо из этого, чтобы оставаться последовательным, мне просто любопытно.
После того, как приведенный ниже ответ указал мне правильное направление, и, как кратко упомянуто в комментарии ниже, я нашел полный ответ в отличном статья Джейка Арчибальда (с примером, почти идентичным моему коду выше), который я бы добавил сюда, а не оставил в комментарии.