Maison  >  Article  >  interface Web  >  Tri forcé de la boucle d'événements javascript

Tri forcé de la boucle d'événements javascript

巴扎黑
巴扎黑original
2017-07-19 15:42:491556parcourir

js monothread

js est monothread, ce qui est plus propice à l'interaction des utilisateurs et aux opérations DOM ; pour une explication détaillée des processus et des threads, vous pouvez cliquer sur le portail bien que le webworker puisse y parvenir ; multi-threading, par essence Il est également monothread. Les threads créés par webworker sont contrôlés par le thread principal et ne peuvent effectuer que des calculs

synchronisation js et asynchrone

Exécution synchrone : cela c'est-à-dire que le thread principal js exécute les tâches dans l'ordre, si vous utilisez webAPI/ajax et d'autres codes, vous attendrez sa réponse et le code suivant ne sera pas exécuté, c'est-à-dire que la tâche suivante doit attendre que la tâche précédente soit terminée ;

Exécution asynchrone : js est monothread et ne peut pas être exécuté. Il a des capacités asynchrones, mais le navigateur peut : lorsque js est exécuté et rencontre une API Web (telle que setTimeout/ajax, etc.), une valeur. sera renvoyé immédiatement, afin de ne pas bloquer le thread principal, et le véritable asynchrone est exécuté par le navigateur, et il sera discuté une fois terminé. La fonction de rappel est poussée dans la file d'attente des messages du thread principal js et attend. pour que le thread principal appelle ;

Mécanisme de boucle d'événement [Event-loop]

Lorsque js est exécuté, son thread principal a une pile d'exécution [appelée personnellement pile d'appel] (pile) et un file d'attente de messages [également appelée file d'attente de tâches ou file d'attente d'événements] (file d'attente d'événements) ; lorsque js rencontre une fonction pendant l'exécution, elle sera poussée sur la pile et sortie de la pile après l'exécution de la fonction, et le thread principal appelle Execute La pile et l'exécuter. S'il rencontre webAPI, il sera exécuté de manière asynchrone ; lorsqu'il n'y a pas de tâche dans la pile d'exécution, le thread principal interrogera la file d'attente des messages. Si la requête réussit, la tâche interrogée sera poussée dans la pile. pile pour l'exécution jusqu'à ce que la pile d'exécution soit vide, et le message sera à nouveau interrogé. La mise en file d'attente pour former une boucle est la fameuse boucle d'événements [Event-loop] puisque l'exécution asynchrone est terminée par le navigateur, il est facile de comprendre pourquoi. Les événements dom opérationnels lorsque le thread js est bloqué seront exécutés séquentiellement après la restauration du thread, [thread principal js La file d'attente des tâches est poussée par le navigateur et le thread js est bloqué == Le thread du navigateur est bloqué ! , même si le thread principal est bloqué, cela n'empêchera pas la tâche d'être poussée dans la file d'attente des tâches] ; dessinez un croquis

Un autre morceau de code :

      // 主线程执行fn1任务  1function fn1(){ 
                console.log("任务1执行")// 遇到webAPI立即返回 这里是undefined值 并交给浏览器对应线程处理 2  // 浏览器收到后 0 毫秒将回调函数推入消息列队; 异步执行setTimeout(function(){// 查询到一个回调任务 入栈执行    5console.log("回调1执行")// 遇到webAPI立即返回 这里是undefined值 并交给浏览器对应线程处理  6  // 浏览器收到后 500   毫秒将回调函数推入消息列队; 异步执行setTimeout(function(){// 查询到一个回调任务 入栈执行    7console.log("回调2执行")
                    },500)
                },0)
            }// 主线程执行fn2任务 3function fn2(){console.log("任务2执行")}// 执行栈没有可执行任务 开始查询消息列队 4
Macrotâches et microtâches

Les files d'attente de messages sont divisées en deux types, à savoir les macrotâches[Task Queue] et les microtâches[Microtasks Queue]

  • macrotâches : , setTimeout, setInterval, E/S, rendu UIsetImmediate

  • microtâches : , process.nextTick, PromisesObject.MutationObserver

Cela soulève une question : qui doit l'exécuter en premier ?

La spécification Promise/A+ indique :

Ici, « code de plate-forme » désigne le moteur, l'environnement et le code d'implémentation de la promesse. En pratique, cette exigence garantit que onFulfilled et onRejected s'exécutent de manière asynchrone. après le tour de la boucle d'événement dans lequel then est appelé, et avec une nouvelle pile
Cela peut être implémenté soit avec un mécanisme de « macro-tâche » tel que setTimeout ou setImmediate, soit avec un mécanisme de « micro-tâche » tel que. MutationObserver ou process.nextTick Puisque l'implémentation de la promesse est considérée comme du code de plate-forme, elle peut elle-même contenir une file d'attente de planification de tâches ou « trampoline » dans laquelle les gestionnaires sont appelés.
En fait, le processus d'exécution. est également facile à comprendre. Il s'agit également d'une requête en boucle. Sur la base de la requête précédente, lors de l'interrogation de la file d'attente de messages, elle interrogera d'abord les
microtâches, puis les macrotâches une fois que toutes ses tâches sont exécutées. tâches de microtâches dans les macrotâches, puis la suivante. La requête sera toujours exécutée en premier tâche de file d'attente des microtâches, puis interrogera les macrotâches. Ceci est répété. jusqu'à ce que la file d'attente des messages [deux files d'attente] n'ait plus de tâches
ok notre code précédent [la fonctionnalité de promesse est es6 donc l'environnement de nœud est utilisé]
console.log(170 Promise(89100 Promise(34562);
// 1 2 3 4 5 6 7 8 9 10

Le processus d'exécution de code ci-dessus :

js exécute la console 1. Lorsque setTimeout est rencontré, il est modifié en exécution asynchrone, et lorsque setTimeout est à nouveau rencontré, il est à nouveau exécuté de manière asynchrone. Ensuite, l'exécution rencontre un. promesse et est poussé dans la file d'attente des tâches de type microtâches pour exécution. Console 2 À ce stade, la pile d'exécution est vide et commence à interroger la file d'attente des messages. Tout d'abord, interrogez les microtâches et découvrez qu'il existe une tâche qui peut. être exécuté. Ensuite, la tâche sera poussée dans la pile pour exécution et 3 4 5 6 sera imprimé en conséquence [Tant que est trouvé. Si les microtâches ne sont pas vides, exécutez jusqu'à ce qu'elles soient vides . ]; Interrogez à nouveau la file d'attente des messages. À ce stade, la file d'attente des microtâches n'a aucune tâche à exécuter. Ensuite, interrogez la file d'attente des macrotâches et recherchez un rappel setTimeout en attente d'exécution. out, imprimant 7 ; interrogez à nouveau la file d'attente. À ce stade, la file d'attente microtâches n'a toujours aucune tâche. Ensuite, interrogez la file d'attente macrotâches et recherchez un rappel setTimeou en attente d'exécution. On constate que la promesse est poussée dans les microtâches. La file d'attente est sortie de la pile et la pile d'exécution est à nouveau vide. Interrogez la file d'attente des messages et constatez que les microtâches ont des tâches qui peuvent être exécutées. Poussez et sortez la pile ; imprimez la réponse 8 9 10 ; maintenant l'exécution se termine et le thread principal est dans un état d'attente ; >

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn