Cet article vous présente l'analyse de la boucle d'événements dans Node. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Le processus de boucle d'événements de Node.js est à peu près le suivant :
┌───────────────────────────┐ ┌─>│ timers │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ pending callbacks │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ │ │ idle, prepare │ │ └─────────────┬─────────────┘ ┌───────────────┐ │ ┌─────────────┴─────────────┐ │ incoming: │ │ │ poll │<─────┤ connections, │ │ └─────────────┬─────────────┘ │ data, etc. │ │ ┌─────────────┴─────────────┐ └───────────────┘ │ │ check │ │ └─────────────┬─────────────┘ │ ┌─────────────┴─────────────┐ └──┤ close callbacks │ └───────────────────────────┘
Chaque étape a sa propre file d'attente de tâches. étape Une fois que toutes les files d'attente de tâches ont été exécutées ou que le nombre maximum de tâches exécutées a été atteint, il entrera dans l'étape suivante.
Cette phase exécutera les tâches planifiées définies par setTimeout
et setInterval
.
Bien sûr, ce timing n'est pas précis, mais une fois le temps de timing dépassé, une fois l'opportunité d'exécution obtenue, elle sera exécutée immédiatement.
Cette étape effectuera certaines opérations liées au système sous-jacent, telles que les erreurs renvoyées par les connexions TCP, etc. Lorsque ces erreurs surviennent, elles seront reportées par Node au cycle suivant.
Cette phase est utilisée pour exécuter des rappels liés aux opérations IO. Node demandera au système d'exploitation si un nouvel événement IO a été déclenché, puis exécutera le rappel correspondant. Presque toutes les opérations, à l'exception des événements programmés, setImmediate()
et close callbacks
seront exécutées dans cette phase.
Cette phase exécutera les tâches définies par setImmediate()
.
Si un socket
ou un handle(句柄)
est fermé brutalement, par exemple via socket.destroy()
, l'événement close
sera émis dans cette phase.
Une fois la boucle d'événements initialisée, elle se déroulera selon le processus indiqué dans la figure ci-dessus :
Tout d'abord, le minuteur sera exécuté en séquence Tâches et pending callback
rappels
puis entrera dans les étapes idle
et prepare
, où une certaine logique interne de Node sera exécutée ;
Entrez ensuite dans la poll
phase de sondage. À ce stade, tous les rappels IO seront exécutés, comme la lecture de fichiers, les opérations réseau, etc. L'étape poll
a une file d'attente de tâches poll queue
. Le processus d'exécution de cette étape est relativement long, comme suit :
Lors de l'entrée dans cette étape, il vérifiera d'abord si la file d'attente de synchronisation timeout
a des tâches exécutables . Si tel est le cas, il passera à 定时器阶段
pour exécution.
S'il n'y a pas de 定时器任务
, la file d'attente des tâches poll queue
sera vérifiée. Si elle n'est pas vide, toutes les tâches seront parcourues et exécutées jusqu'à ce qu'elles soient toutes exécutées ou la. le nombre maximum de tâches pouvant être exécutées est atteint.
poll queue
Une fois l'exécution de la file d'attente des tâches terminée, il vérifiera s'il y a des tâches dans la file d'attente des tâches setImmediate
. Si tel est le cas, la boucle d'événements sera transférée au suivant <. 🎜> scène. check
, alors Node attendra ici l'arrivée de nouveaux rappels IO et les exécutera immédiatement. setImmediate
Remarque : Cette attente ne continuera pas éternellement, mais après avoir atteint une limite, passez à l'étape suivante pour l'exécution.
setTimeout()
setImmediate()
C'est-à-dire : dans Node,
sera converti en setTimeout(callback, 0)
. setTimeout(callback, 1)
Veuillez vous référer ici pour plus de détails. L'ordre d'exécution de
setTimeout()
setImmediate()
setTimeout(function() { console.log('timeout'); }, 0); setImmediate(function() { console.log('immediate'); });
que nous avons défini a été converti en setTimeout(callback, 0)
, donc en entrant dans l'étape setTimeout(callback, 1)
, il sera jugé en fonction de l'heure actuelle si le le timing a dépassé 定时器
. 1ms
, la tâche 1ms
sera exécutée en premier s'il y a un retard et cette fois ; atteint la limite de immediate
, 1ms
La tâche sera exécutée en premier. timeout
sera exécutée en premier pour les raisons suivantes :setImmediate
进入 poll phase
轮询阶段之前会先检查是否有 timer
定时任务。
如果没有 timer
定时任务,才会执行后面的 IO 回调。
我们在 IO 回调中设置 setTimeout
定时任务,这时已经过了 timer
检查阶段,所以 timer
定时任务会被推迟到下一个循环中执行。
process.nextTick()
无论在事件循环的哪个阶段,只要使用 process.nextTick()
添加了回调任务,Node 都会在进入下一阶段之前把 nextTickQueue
队列中的任务执行完。
setTimeout(function() { setImmediate(() => { console.log('immediate'); }); process.nextTick(() => { console.log('nextTick'); }); }, 0); // nextTick // immediate
上述代码中,总是先执行 nextTick
任务,就是因为在循环在进入下一个阶段之前会先执行 nextTickQueue
中的任务。下面代码的执行结果也符合预期。
setImmediate(() => { setTimeout(() => { console.log('timeout'); }, 0); process.nextTick(() => { console.log('nextTick'); }); }); // nextTick // timeout
相关推荐:
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!