


Cet article vous amènera à comprendre la file d'attente du minuteur dans la boucle d'événements Node
Dans l'article précédent, nous avons discuté de la file d'attente des microtâches et de son ordre de priorité au sein de chaque file d'attente. Dans cet article, nous aborderons les files d'attente de minuterie, une autre file d'attente dans Node.js pour gérer le code asynchrone.
Avant de plonger dans les files d’attente de minuterie, jetons un coup d’œil rapide aux files d’attente de microtâches. Pour mettre la fonction de rappel en file d'attente dans la file d'attente des microtâches, nous utilisons des fonctions telles que process.nextTick()
et Promise.resolve()
. Les files d'attente de microtâches ont la priorité la plus élevée lorsqu'il s'agit d'exécuter du code asynchrone dans Node.js. [Tutoriels associés recommandés : tutoriel vidéo nodejsprocess.nextTick()
和 Promise.resolve()
等函数。当涉及到执行 Node.js 中的异步代码时,微任务队列具有最高优先级。【相关教程推荐:nodejs视频教程、编程教学】
入队回调函数
现在我们转到计时器队列。要将回调函数排入计时器队列,我们可以使用 setTimeout
和 setInterval
等函数。为了方便说明,本文将使用 setTimeout
。
为了理解计时器队列的执行顺序,我们会进行一系列实验,在微任务队列和计时器队列中入队任务。
实验三
代码
// index.js setTimeout(() => console.log("this is setTimeout 1"), 0); setTimeout(() => console.log("this is setTimeout 2"), 0); setTimeout(() => console.log("this is setTimeout 3"), 0); process.nextTick(() => console.log("this is process.nextTick 1")); process.nextTick(() => { console.log("this is process.nextTick 2"); process.nextTick(() => console.log("this is the inner next tick inside next tick") ); }); process.nextTick(() => console.log("this is process.nextTick 3")); Promise.resolve().then(() => console.log("this is Promise.resolve 1")); Promise.resolve().then(() => { console.log("this is Promise.resolve 2"); process.nextTick(() => console.log("this is the inner next tick inside Promise then block") ); }); Promise.resolve().then(() => console.log("this is Promise.resolve 3"));
译注:大家不用紧张,这段代码就是在上篇“福利实验”的基础上,在开头加了 3 个
setTimeout
语句。
该代码包含三个 process.nextTick()
的调用,三个 Promise.resolve()
的调用和三个 setTimeout
的调用。每个回调函数记录适当的消息。所有三个 setTimeout
调用都有 0ms
的延迟,这表示在执行每个 setTimeout
语句时,回调函数都立即入队到计时器队列等待。第二次 process.nextTick()
和第二次 Promise.resolve()
都有一个额外的 process.nextTick()
语句,并且每个都带有一个回调函数。
可视化
当调用栈执行所有语句后,在 nextTick 队列中有 3 个回调,在 Promise 队列中有 3 个回调,在计时器队列中也有 3 个回调。没有代码要执行,控制权进入事件循环。
nextTick 队列具有最高优先级,其次是 Promise 队列,然后是计时器队列。从 nextTick 队列中获取第1 个回调并执行它,将一条消息记录到控制台。接着获取第 2 个回调并执行它,这也会记录一条消息。第 2 个回调包含 process.nextTick()
的调用,该方法将新的回调添加到了 nextTick 队列中。继续执行,并获取和执行第 3 个回调以及记录一条消息。最后,我们将新添加到 nextTick 队列的回调函数取出并在调用栈中执行,从而在控制台上输出了第四条日志信息。
当 nextTick 队列为空时,事件循环转向 Promise 队列。从队列中获取第 1 个回调,在控制台打印一条信息,第二个回调效果类似,并且还向 nextTick 队列添加了一个回调。 Promise 中的第 3 个回调被执行,接着日志消息被输出。此时 Promise 队列已空,事件循环检查 nextTick 队列是否存在新的回调,找到之后同样将消息记录到控制台。
现在,两个微任务队列都空了,事件循环转向计时器队列。我们有三个回调,每个回调依次从计时器队列中取出并在调用栈上执行,将分别打印 "setTimeout 1"、"setTimeout 2" 和 "setTimeout 3"。
this is process.nextTick 1 this is process.nextTick 2 this is process.nextTick 3 this is the inner next tick inside next tick this is Promise.resolve 1 this is Promise.resolve 2 this is Promise.resolve 3 this is the inner next tick inside Promise then block this is setTimeout 1 this is setTimeout 2 this is setTimeout 3
推论
微任务队列中的回调函数会在定时器队列中的回调函数之前执行。
到目前为止,优先顺序是 nextTick 队列,其次是 Promise 队列,然后是定时器队列。现在让我们继续进行下一个实验。
实验四
// index.js setTimeout(() => console.log("this is setTimeout 1"), 0); setTimeout(() => { console.log("this is setTimeout 2"); process.nextTick(() => console.log("this is inner nextTick inside setTimeout") ); }, 0); setTimeout(() => console.log("this is setTimeout 3"), 0); process.nextTick(() => console.log("this is process.nextTick 1")); process.nextTick(() => { console.log("this is process.nextTick 2"); process.nextTick(() => console.log("this is the inner next tick inside next tick") ); }); process.nextTick(() => console.log("this is process.nextTick 3")); Promise.resolve().then(() => console.log("this is Promise.resolve 1")); Promise.resolve().then(() => { console.log("this is Promise.resolve 2"); process.nextTick(() => console.log("this is the inner next tick inside Promise then block") ); }); Promise.resolve().then(() => console.log("this is Promise.resolve 3"));
第四个实验的代码大部分与第三个相同,只有一个例外。传递给第二个 setTimeout
函数的回调函数现在包含 process.nextTick()
, Enseignement de la programmation
Fonction de rappel de mise en file d'attente
C'est parti à la file d'attente du minuteur. Pour mettre une fonction de rappel en file d'attente dans une file d'attente de minuterie, nous pouvons utiliser des fonctions telles que setTimeout
et setInterval
. Pour faciliter l'explication, cet article utilisera setTimeout
. Afin de comprendre l'ordre d'exécution de la file d'attente du minuteur, nous mènerons une série d'expériences pour mettre les tâches en file d'attente dans la file d'attente des microtâches et la file d'attente du minuteur.
🎜Expérience 3🎜
🎜Code🎜🎜this is process.nextTick 1
this is process.nextTick 2
this is process.nextTick 3
this is the inner next tick inside next tick
this is Promise.resolve 1
this is Promise.resolve 2
this is Promise.resolve 3
this is the inner next tick inside Promise then block
this is setTimeout 1
this is setTimeout 2
this is inner nextTick inside setTimeout
this is setTimeout 3
Copier après la connexionCopier après la connexion🎜Annotation : Ne soyez pas nerveux, ce paragraphe Le code est basé sur la précédente "Welfare Experiment", avec trois instructions setTimeout
ajoutées au début. 🎜
🎜Ce code contient trois appels à process.nextTick()
, trois appels à Promise.resolve()
et trois setTimeout< /code> appel. Chaque fonction de rappel enregistre le message approprié. Les trois appels <code>setTimeout
ont un délai de 0 ms
, ce qui signifie que la fonction de rappel est immédiatement mise en file d'attente dans le minuteur lorsque chaque instruction setTimeout
est exécutée. Le serveur la file d'attente attend. Le deuxième process.nextTick()
et le deuxième Promise.resolve()
ont tous deux une instruction process.nextTick()
supplémentaire, et chacun vient avec une fonction de rappel. 🎜🎜Visualisation🎜🎜🎜
Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dang Dangdang Dangdang Dangdang Dangda Dangda pile a exécuté toutes les phrases. Il y a 3 rappels dans la file d'attente Promise, et il y a 3 rappels dans la file d'attente Promise. file d'attente de minuterie. Il n'y a pas de code à exécuter et le contrôle passe à la boucle d'événements. 🎜🎜La file d'attente nextTick a la priorité la plus élevée, suivie de la file d'attente Promise, puis de la file d'attente du minuteur. Obtenez le premier rappel de la file d'attente nextTick et exécutez-le en enregistrant un message sur la console. Ensuite, récupérez le 2ème rappel et exécutez-le, ce qui enregistrera également un message. Le deuxième rappel contient un appel à process.nextTick()
, qui ajoute un nouveau rappel à la file d'attente nextTick. Continuez l'exécution, récupérez et exécutez le 3ème rappel et enregistrez un message. Enfin, nous retirons la fonction de rappel nouvellement ajoutée à la file d'attente nextTick et l'exécutons dans la pile d'appels, affichant ainsi le quatrième message de journal sur la console. 🎜🎜Lorsque la file d'attente nextTick est vide, la boucle d'événements se tourne vers la file d'attente Promise. Obtenez le premier rappel de la file d'attente et imprimez un message sur la console. Le deuxième rappel a un effet similaire et ajoute également un rappel à la file d'attente nextTick. Le troisième rappel de la promesse est exécuté et le message de journal est affiché. À ce stade, la file d'attente Promise est vide et la boucle d'événements vérifie la file d'attente nextTick pour voir s'il y a un nouveau rappel. Une fois trouvé, le message est également enregistré dans la console. 🎜🎜Maintenant, les deux files d'attente de microtâches sont vides et la boucle d'événements se déplace vers la file d'attente du minuteur. Nous avons trois rappels, dont chacun est extrait de la file d'attente du minuteur et exécuté sur la pile d'appels, imprimera respectivement "setTimeout 1", "setTimeout 2" et "setTimeout 3". 🎜// index.js
setTimeout(() => console.log("this is setTimeout 1"), 1000);
setTimeout(() => console.log("this is setTimeout 2"), 500);
setTimeout(() => console.log("this is setTimeout 3"), 0);
Copier après la connexionCopier après la connexion🎜Inference🎜🎜🎜La fonction de rappel dans la file d'attente des microtâches sera exécutée avant la fonction de rappel dans la file d'attente du minuteur. 🎜
🎜Jusqu'à présent, l'ordre de priorité est la file d'attente nextTick, suivie de la file d'attente Promise, puis de la file d'attente du minuteur. Passons maintenant à l'expérience suivante. 🎜🎜Expérience 4🎜
this is setTimeout 3
this is setTimeout 2
this is setTimeout 1
Copier après la connexionCopier après la connexion🎜Le code de la quatrième expérience est essentiellement le même que celui de la troisième, à une exception près. La fonction de rappel passée à la deuxième fonction setTimeout
contient désormais un appel à process.nextTick()
. 🎜🎜🎜Visualisation🎜🎜🎜🎜🎜
this is process.nextTick 1 this is process.nextTick 2 this is process.nextTick 3 this is the inner next tick inside next tick this is Promise.resolve 1 this is Promise.resolve 2 this is Promise.resolve 3 this is the inner next tick inside Promise then block this is setTimeout 1 this is setTimeout 2 this is inner nextTick inside setTimeout this is setTimeout 3
setTimeout
ajoutées au début. 🎜
process.nextTick()
, qui ajoute un nouveau rappel à la file d'attente nextTick. Continuez l'exécution, récupérez et exécutez le 3ème rappel et enregistrez un message. Enfin, nous retirons la fonction de rappel nouvellement ajoutée à la file d'attente nextTick et l'exécutons dans la pile d'appels, affichant ainsi le quatrième message de journal sur la console. 🎜🎜Lorsque la file d'attente nextTick est vide, la boucle d'événements se tourne vers la file d'attente Promise. Obtenez le premier rappel de la file d'attente et imprimez un message sur la console. Le deuxième rappel a un effet similaire et ajoute également un rappel à la file d'attente nextTick. Le troisième rappel de la promesse est exécuté et le message de journal est affiché. À ce stade, la file d'attente Promise est vide et la boucle d'événements vérifie la file d'attente nextTick pour voir s'il y a un nouveau rappel. Une fois trouvé, le message est également enregistré dans la console. 🎜🎜Maintenant, les deux files d'attente de microtâches sont vides et la boucle d'événements se déplace vers la file d'attente du minuteur. Nous avons trois rappels, dont chacun est extrait de la file d'attente du minuteur et exécuté sur la pile d'appels, imprimera respectivement "setTimeout 1", "setTimeout 2" et "setTimeout 3". 🎜// index.js setTimeout(() => console.log("this is setTimeout 1"), 1000); setTimeout(() => console.log("this is setTimeout 2"), 500); setTimeout(() => console.log("this is setTimeout 3"), 0);
🎜Inference🎜🎜🎜La fonction de rappel dans la file d'attente des microtâches sera exécutée avant la fonction de rappel dans la file d'attente du minuteur. 🎜
🎜Jusqu'à présent, l'ordre de priorité est la file d'attente nextTick, suivie de la file d'attente Promise, puis de la file d'attente du minuteur. Passons maintenant à l'expérience suivante. 🎜🎜Expérience 4🎜
this is setTimeout 3
this is setTimeout 2
this is setTimeout 1
Copier après la connexionCopier après la connexion🎜Le code de la quatrième expérience est essentiellement le même que celui de la troisième, à une exception près. La fonction de rappel passée à la deuxième fonction setTimeout
contient désormais un appel à process.nextTick()
. 🎜🎜🎜Visualisation🎜🎜🎜🎜🎜
this is setTimeout 3 this is setTimeout 2 this is setTimeout 1
让我们应用从之前的实验中学到的知识,快进到回调在微任务队列中已经被执行的点。假设我们有三个回调在计时器队列中排队等待。第一个回调出队并在调用堆栈上执行,“setTimeout 1”消息打印到控制台。事件循环继续运行第二个回调,“setTimeout 2”消息打印到控制台。同时,也会有一个回调函数入队了 nextTick 队列。
在执行计时器队列中的每个回调后,事件循环会返回检查微任务队列。检查 nextTick 队列确定需要执行的回调函数。这时第二个 setTimeout
推入的回调函数出队并在调用栈上执行,结果“inner nextTick”消息打印到控制台。
现在微任务队列为空了,控制权返回到计时器队列,最后一个回调被执行,控制台上显示消息“setTimeout 3”。
this is process.nextTick 1 this is process.nextTick 2 this is process.nextTick 3 this is the inner next tick inside next tick this is Promise.resolve 1 this is Promise.resolve 2 this is Promise.resolve 3 this is the inner next tick inside Promise then block this is setTimeout 1 this is setTimeout 2 this is inner nextTick inside setTimeout this is setTimeout 3
推论
微任务队列中的回调函数会在定时器队列中的回调函数执行之间被执行。
实验五
代码
// index.js setTimeout(() => console.log("this is setTimeout 1"), 1000); setTimeout(() => console.log("this is setTimeout 2"), 500); setTimeout(() => console.log("this is setTimeout 3"), 0);
该代码包含三个 setTimeout
语句,包含三个不同的、入队时机不一样的回调函数。第一个 setTimeout
延迟 1000 毫秒,第二个延迟 500 毫秒,第三个延迟 0 毫秒。当执行这些回调函数时,它们只是简单地将一条消息记录到控制台中。
可视化
由于代码片段的执行非常简单,因此我们将跳过可视化实验。当多个 setTimeout
调用被发出时,事件循环首先排队最短延迟的一个并在其他之前执行。结果,我们观察到“setTimeout 3”先执行,然后是“setTimeout 2”,最后是“setTimeout 1”。
this is setTimeout 3 this is setTimeout 2 this is setTimeout 1
推论
计时器队列回调按照先进先出(FIFO)的顺序执行。
总结
实验表明,微任务队列中的回调比定时器队列中的回调具有更高优先级,并且微任务队列中的回调在定时器队列中的回调之间执行。定时器队列遵循先进先出(FIFO)顺序。
原文链接:Visualizing The Timer Queue in Node.js Event Loop,2023年4月4日,by Vishwas Gopinath
更多node相关知识,请访问:nodejs 教程!
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP et Vue : une combinaison parfaite d'outils de développement front-end À l'ère actuelle de développement rapide d'Internet, le développement front-end est devenu de plus en plus important. Alors que les utilisateurs ont des exigences de plus en plus élevées en matière d’expérience des sites Web et des applications, les développeurs front-end doivent utiliser des outils plus efficaces et plus flexibles pour créer des interfaces réactives et interactives. En tant que deux technologies importantes dans le domaine du développement front-end, PHP et Vue.js peuvent être considérés comme une arme parfaite lorsqu'ils sont associés. Cet article explorera la combinaison de PHP et Vue, ainsi que des exemples de code détaillés pour aider les lecteurs à mieux comprendre et appliquer ces deux éléments.

Lors des entretiens de développement front-end, les questions courantes couvrent un large éventail de sujets, notamment les bases HTML/CSS, les bases JavaScript, les frameworks et les bibliothèques, l'expérience du projet, les algorithmes et les structures de données, l'optimisation des performances, les requêtes inter-domaines, l'ingénierie front-end, les modèles de conception et les nouvelles technologies et tendances. Les questions de l'intervieweur sont conçues pour évaluer les compétences techniques du candidat, son expérience en matière de projet et sa compréhension des tendances du secteur. Par conséquent, les candidats doivent être parfaitement préparés dans ces domaines pour démontrer leurs capacités et leur expertise.

Tutoriel JavaScript : Comment obtenir le code d'état HTTP, des exemples de code spécifiques sont requis Préface : Dans le développement Web, l'interaction des données avec le serveur est souvent impliquée. Lors de la communication avec le serveur, nous devons souvent obtenir le code d'état HTTP renvoyé pour déterminer si l'opération a réussi et effectuer le traitement correspondant en fonction de différents codes d'état. Cet article vous apprendra comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournira quelques exemples de codes pratiques. Utilisation de XMLHttpRequest

Django est un framework d'application Web écrit en Python qui met l'accent sur un développement rapide et des méthodes propres. Bien que Django soit un framework Web, pour répondre à la question de savoir si Django est un front-end ou un back-end, vous devez avoir une compréhension approfondie des concepts de front-end et de back-end. Le front-end fait référence à l'interface avec laquelle les utilisateurs interagissent directement, et le back-end fait référence aux programmes côté serveur. Ils interagissent avec les données via le protocole HTTP. Lorsque le front-end et le back-end sont séparés, les programmes front-end et back-end peuvent être développés indépendamment pour mettre en œuvre respectivement la logique métier et les effets interactifs, ainsi que l'échange de données.

En tant que langage de programmation rapide et efficace, le langage Go est très populaire dans le domaine du développement back-end. Cependant, peu de gens associent le langage Go au développement front-end. En fait, l’utilisation du langage Go pour le développement front-end peut non seulement améliorer l’efficacité, mais également ouvrir de nouveaux horizons aux développeurs. Cet article explorera la possibilité d'utiliser le langage Go pour le développement front-end et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre ce domaine. Dans le développement front-end traditionnel, JavaScript, HTML et CSS sont souvent utilisés pour créer des interfaces utilisateur.

Django : Un framework magique capable de gérer à la fois le développement front-end et back-end ! Django est un framework d'application Web efficace et évolutif. Il est capable de prendre en charge plusieurs modèles de développement Web, notamment MVC et MTV, et peut facilement développer des applications Web de haute qualité. Django prend non seulement en charge le développement back-end, mais peut également créer rapidement des interfaces frontales et obtenir un affichage de vue flexible via un langage de modèle. Django combine le développement front-end et le développement back-end dans une intégration transparente, afin que les développeurs n'aient pas à se spécialiser dans l'apprentissage.

Combinaison de Golang et de la technologie front-end : pour explorer le rôle de Golang dans le domaine front-end, des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et des applications mobiles, la technologie front-end est devenue de plus en plus importante. Dans ce domaine, Golang, en tant que puissant langage de programmation back-end, peut également jouer un rôle important. Cet article explorera comment Golang est combiné avec la technologie front-end et démontrera son potentiel dans le domaine front-end à travers des exemples de code spécifiques. Le rôle de Golang dans le domaine front-end est celui d'un outil efficace, concis et facile à apprendre.

Introduction à la méthode d'obtention du code d'état HTTP en JavaScript : Dans le développement front-end, nous devons souvent gérer l'interaction avec l'interface back-end, et le code d'état HTTP en est une partie très importante. Comprendre et obtenir les codes d'état HTTP nous aide à mieux gérer les données renvoyées par l'interface. Cet article explique comment utiliser JavaScript pour obtenir des codes d'état HTTP et fournit des exemples de code spécifiques. 1. Qu'est-ce que le code d'état HTTP ? Le code d'état HTTP signifie que lorsque le navigateur lance une requête au serveur, le service
