Es mejor escribir código que no se base en el momento de las devoluciones de llamadas inmediatas (como microtasks vs macrotasks), pero dejemos eso de lado por el momento.
setTimeout
pone en cola un macrotask, que, como mínimo, espera comenzar hasta que finalicen todos los microtasks (y los microtasks que generan). Aquí hay un ejemplo:
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');
El comportamiento de una .then
Promesa resuelta es fundamentalmente diferente del comportamiento de una setTimeout
devolución de llamada inmediata : la Promesa .then
se ejecutará primero, incluso si setTimeout
primero se puso en cola. Pero solo los navegadores modernos admiten Promesas. ¿Cómo puede la funcionalidad especial de un microtask ser debidamente rellenada si Promise
no existe?
Si intentas imitar la microtask de un usuario .then
usando setTimeout
, estarás haciendo cola con una macrotask, no con una microtask, por lo que el mal polifundido .then
no se ejecutará en el momento adecuado si una macrotask ya está en cola.
Hay una solución que usa MutationObserver
, pero se ve fea y no MutationObserver
es para lo que sirve. Además, MutationObserver
no es compatible con IE10 y versiones anteriores. Si se quiere poner en cola una microtask en un entorno que no admite Promesas de forma nativa, ¿hay alguna alternativa mejor?
(En realidad, no estoy tratando de admitir IE10; este es solo un ejercicio teórico sobre cómo se pueden poner en cola las microtask sin Promesas)
schedule.js
será esclarecedor.