Avant, je pensais simplement que parce que la fonction s'exécute très rapidement, même si le temps d'exécution de setTimeout est de 0, elle ne sera pas sortie immédiatement, mais attendra que la fonction soit exécutée avant de sortir. Ce n’est qu’à moitié vrai.
En fait, son mécanisme de fonctionnement est le mécanisme de boucle d'événements en js. Dans ce mécanisme de boucle, il est lié à la pile d'appels et à la file d'attente des tâches.
Donnez un exemple simple :
console.log(1); setTimeout(function(){console.log(2);}, 0);console.log(3);
1 Exécutez la première phrase, placez-la dans la pile d'appels et produisez 1
.
2. La première phrase est retirée de la pile et la deuxième phrase est exécutée puisqu'elle est exécutée de manière asynchrone, elle est transmise à d'autres modules.
3. Après l'exécution, placez la
fonction de rappel dans la file d'attente des tâches
4. put L'instruction est poussée sur la pile et exécutée, et 3
5 est sortie L'instruction est retirée de la pile et la pile d'appels est vide à ce moment. Commencez à exécuter la tâche de la file d'attente des tâches et obtenez la sortie 2
Par conséquent, le résultat de la sortie est
comme prévu.
Nous savons que la fonction de rappel de Promise n'est pas transmise, mais est appelée en utilisant then. Par conséquent, la fonction définie dans Promise doit être exécutée immédiatement, puis sa fonction de rappel est placée dans la file d'attente.
Un concept important est également mentionné dans l'article référencé :
Regardez un autre exemple :macro-tâcheComprend : script (code global), setTimeout, setInterval, setImmediate, I/O, Rendu de l'interface utilisateur. La
micro-tâche comprend : process.nextTick, Promises, Object.observe, MutationObserver Séquence d'exécution : la pile d'appels de fonction est effacée, ne laissant que le contexte d'exécution global, puis toutes les micro-tâches sont exécutées. Une fois que toutes les micro-tâches exécutables ont été exécutées. La boucle exécute à nouveau une file d'attente de tâches dans la macro-tâche, puis exécute toutes les micro-tâches après l'exécution, et la boucle continue.
(function test() { setTimeout(function() {console.log(4)}, 0); new Promise(function executor(resolve) { console.log(1); for( var i=0 ; i<10000 ; i++ ) { i == 9999 && resolve(); } console.log(2); }).then(function() { console.log(5); }); console.log(3);})()
1. Lorsque setTimeout est rencontré, il est transmis à d'autres modules pour exécution. Après exécution, le rappel est placé dans la macro-tâche
2. la fonction à l'intérieur est exécutée immédiatement et 1 est sorti.
3. La boucle démarre, rencontre solve() et modifie le statut de la promesse pour qu'elle soit remplie. Continuez l'exécution et la sortie 2.
4. Lorsque vous rencontrez alors, placez le rappel dans la micro-tâche.
5. Continuez l'exécution et la sortie 3.
6. L'exécution de la pile d'appels est terminée. Commencez à exécuter la fonction de rappel dans la micro-tâche et sortie 5.
7. Une fois la micro-tâche exécutée, la fonction de rappel dans la macro-tâche commence à être exécutée et 4 est affiché.
8. La fin.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!