Il est préférable d'écrire du code qui ne dépend pas de la synchronisation des rappels immédiats (comme les microtâches contre les macrotâches), mais mettons cela de côté pour le moment.
setTimeout
met en file d'attente une macrotâche, qui, au minimum, attend de démarrer jusqu'à ce que tous les microtâches (et les microtâches qu'ils génèrent) se terminent. Voici un exemple:
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');
Le comportement d'un .then
sur une promesse résolue est fondamentalement différent du comportement d'un setTimeout
rappel immédiat - la promesse .then
s'exécutera en premier, même si le a setTimeout
été mis en file d'attente en premier. Mais seuls les navigateurs modernes prennent en charge Promises. Comment la fonctionnalité spéciale d'une microtâche peut-elle être correctement remplie si elle Promise
n'existe pas?
Si vous essayez d'imiter une .then
microtâche en utilisant un setTimeout
, vous allez mettre en file d'attente une macrotâche, pas une microtâche, de sorte que la mauvaise polyfonction .then
ne fonctionnera pas au bon moment si une macrotâche est déjà en file d'attente.
Il y a une solution à utiliser MutationObserver
, mais elle a l'air moche, et ce n'est pas MutationObserver
pour ça . En outre, MutationObserver
n'est pas pris en charge sur IE10 et versions antérieures. Si l'on veut mettre en file d'attente une microtâche dans un environnement qui ne prend pas en charge nativement Promises, existe-t-il de meilleures alternatives?
(Je n'essaie pas réellement de prendre en charge IE10 - ce n'est qu'un exercice théorique sur la façon dont les microtâches peuvent être mises en file d'attente sans promesses)
la source
schedule.js
sera instructif.Réponses:
Si nous parlons d'IE, vous pouvez utiliser
setImmediate
https://developer.mozilla.org/en-US/docs/Web/API/Window/setImmediate
setImmediate
est pris en charge sur IE10. Donc, plus une version IE.Et, si vous êtes intéressé, plus Node.js.
Il existe d'autres polyfills possibles, voici quelques implémentations: https://github.com/YuzuJS/setImmediate/blob/master/setImmediate.js (celui-ci est mentionné dans MDN) https://github.com/taylorhakes/ setAsap / blob / master / setAsap.js (un plus simple)
Et comme presque tous les polyfills, ils sont aussi laids.
Mais de toute façon, voici un exemple dans son essence (en utilisant postMessage), et je pense qu'il est le moins laid de tous (mais aussi pas un vrai polyfill)
la source
J'ai vu que les
mutationObserver
rappels utilisent des microtâches, et heureusement, IE11 le prend en charge, j'ai donc eu l'idée de mettre en file d'attente une microtâche dans IE11 en enregistrant le rappel et en déclenchant immédiatement l'observateur en changeant un élément:Vous pouvez ouvrir IE11 et voir le fonctionnement ci-dessus, mais le code semble étrange.
la source