É melhor escrever um código que não dependa do tempo de retornos de chamada imediatos (como microtasks vs macrotasks), mas vamos deixar isso de lado por enquanto.
setTimeout
enfileira uma macrotask, que, no mínimo, espera para iniciar até que todas as microtasks (e microtasks que elas geram) terminem. Aqui está um exemplo:
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');
O comportamento de uma .then
Promessa resolvida é fundamentalmente diferente do comportamento de um setTimeout
retorno de chamada imediato - a Promessa .then
será executada primeiro, mesmo que tenha setTimeout
sido colocada na fila primeiro. Mas apenas navegadores modernos suportam promessas. Como a funcionalidade especial de uma microtask pode ser preenchida corretamente se Promise
não existe?
Se você tentar imitar uma .then
microtask de uma usando setTimeout
, você estará enfileirando uma macrotask, não uma microtask, para que o mal preenchido com polietileno .then
não seja executado no momento certo se uma macrotask já estiver na fila.
Existe uma solução em uso MutationObserver
, mas parece feia e não MutationObserver
é para isso. Além disso, MutationObserver
não é suportado no IE10 e versões anteriores. Se alguém deseja enfileirar uma microtask em um ambiente que não oferece suporte nativo ao Promises, existem alternativas melhores?
(Na verdade, não estou tentando oferecer suporte ao IE10 - este é apenas um exercício teórico sobre como as microtasks podem ser enfileiradas sem promessas)
fonte
schedule.js
será esclarecedor.Respostas:
Se estamos falando sobre o IE, você pode usar
setImmediate
https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
setImmediate
é suportado no IE10. Então, mais uma versão do IE.E, se você estiver interessado, mais Node.js.
Existem outros polyfills possíveis, eis algumas implementações: https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (este é mencionado no MDN) https://github.com/taylorhakes/ setAsap / blob / master / setAsap.js (mais simples)
E como quase todos os polyfills, eles também são feios.
Mas de qualquer maneira, aqui está um exemplo em sua essência (usando postMessage), e acho que é menos feio de todos (mas também não é um verdadeiro polyfill)
fonte
Vi que os
mutationObserver
retornos de chamada usam microtasks e, felizmente, o IE11 suporta, então tive a ideia de enfileirar um microtask no IE11 salvando o retorno de chamada e acionando imediatamente o observador alterando um elemento:Você pode abrir o IE11 e ver o trabalho acima, mas o código parece estranho.
fonte