


Comment utiliser EventEmitter pour gérer les événements dans Node.js ?
Dans ce tutoriel, nous découvrons la classe EvenEmitter
native de Node.js. Après avoir appris, vous comprendrez les événements, comment utiliser EvenEmitter
et comment utiliser les événements dans vos programmes. De plus, vous apprendrez également comment la classe EventEmitter
s'étend à partir d'autres modules locaux et comprendrez les principes qui la sous-tendent à travers quelques exemples.
Tutoriel recommandé : tutoriel node js
En bref, cet article couvre tout sur la classe EventEmitter
.
Qu'est-ce qu'un événement ?
L'architecture basée sur les événements est très courante aujourd'hui. Les programmes basés sur les événements peuvent générer, détecter et répondre à divers événements.
La partie centrale de Node.js est pilotée par les événements, et de nombreux modules tels que le système de fichiers (fs
) et stream
sont eux-mêmes écrits en utilisant EventEmitter
.
Dans la programmation événementielle, un événement est le résultat d'une ou plusieurs actions, qui peuvent être une opération d'un utilisateur ou la sortie de synchronisation d'un capteur, etc.
Nous pouvons considérer les programmes événementiels comme un modèle de publication-abonnement, dans lequel les éditeurs déclenchent des événements et les abonnés écoutent les événements et prennent les mesures appropriées.
Par exemple, imaginez qu'il existe un serveur sur lequel les utilisateurs peuvent télécharger des images. En programmation événementielle, une action telle que télécharger une image émettra un événement, qui aura également 1 à n abonnés afin d'en profiter.
Une fois l'événement de téléchargement déclenché, un abonné peut le faire savoir et réagir à l'administrateur du site en envoyant un e-mail à l'administrateur du site ; un autre abonné peut collecter des informations sur l'action et les enregistrer dans la base de données.
Ces événements sont généralement indépendants les uns des autres, bien qu'ils puissent également être dépendants les uns des autres.
Qu'est-ce qu'EventEmitter ? La classe
EventEmitter
est une classe intégrée de Node.js, située dans le module events
. Selon la description dans la documentation :
La plupart des API principales de Node.js sont implémentées sur la base d'une architecture événementielle asynchrone idiomatique, dans laquelle certains types d'objets (appelés " émetteur ») émettent des événements nommés qui provoquer des appels à des Function
objets ("auditeurs")"
Cette classe peut à certains égards être décrite comme une implémentation d'un assistant pour le modèle de publication-abonnement, car elle peut aider les émetteurs d'événements (éditeurs) à publier des événements (messages) aux auditeurs (abonnés) de manière simple
Créer des EventEmitters
Cela dit, faisons-le d'abord. Créer un EventEmitter
est plus pratique, soit en créant une instance. de la classe elle-même ou en implémentant une classe personnalisée, puis en créant un objet
de l'objet EventEmitter
Commencez par un exemple simple : créez un qui émet un. événement contenant des informations d'exécution du programme chaque seconde EventEmitter
depuis le module events
: EventEmitter
const { EventEmitter } = require('events');
: EventEmitter
const timerEventEmitter = new EventEmitter();
timerEventEmitter.emit("update");
Laissez d'abord cet événement se répéter toutes les secondes. Utilisez la méthode
pour créer une minuterie et publiez-la toutes les secondes. Événement :let currentTime = 0; // 每秒触发一次 update 事件 setInterval(() => { currentTime++; timerEventEmitter.emit('update', currentTime); }, 1000);
setInterval()
update
est utilisée pour accepter le nom et les paramètres de l'événement. Passez comme nom de l'événement et comme heure depuis le démarrage du programme. La méthode 🎜> déclenche l'émetteur, qui transmet l'événement avec les informations que nous avons fournies. Après avoir préparé l'émetteur d'événement, abonnez-vous à l'écouteur d'événement pour. it : EventEmitter
timerEventEmitter.on('update', (time) => { console.log('从发布者收到的消息:'); console.log(`程序已经运行了 ${time} 秒`); });
update
Créez l'écouteur via la méthode currentTime
et transmettez-le. Le nom de l'événement pour spécifier à quel événement vous souhaitez attacher l'écouteur. Sur l'événement , exécutez une méthode qui enregistre le. time. Le deuxième paramètre de la fonction emit()
on()
L'exécution du code affichera : update
从发布者收到的消息: 程序已经运行了 1 秒 从发布者收到的消息: 程序已经运行了 2 秒 从发布者收到的消息: 程序已经运行了 3 秒 ...
pour vous abonner : on()
timerEventEmitter.once('update', (time) => { console.log('从发布者收到的消息:'); console.log(`程序已经运行了 ${time} 秒`); });
从发布者收到的消息: 程序已经运行了 1 秒
EventEmitteronce()
Avec plusieurs auditeurs
Voici un autre programme émetteur d'événements, il y a trois auditeurs, le premier auditeur met à jour l'heure toutes les secondes, le deuxième auditeur se déclenche lorsque le timer est sur le point de se terminer, et le dernier. se déclenche lorsque le timer est terminé :
: Déclenche une fois par seconde
: Déclenche à la fin du compte à rebours-
update
: Déclenchez 2 secondes avant la fin du compte à rebours -
end
d'abord Écrivez une fonction qui crée cet émetteur d'événement :
const countDown = (countdownTime) => { const eventEmitter = new EventEmitter(); let currentTime = 0; // 每秒触发一次 update 事件 const timer = setInterval(() => { currentTime++; eventEmitter.emit('update', currentTime); // 检查计时是否已经结束 if (currentTime === countdownTime) { clearInterval(timer); eventEmitter.emit('end'); } // 检查计时是否会在 2 秒后结束 if (currentTime === countdownTime - 2) { eventEmitter.emit('end-soon'); } }, 1000); return eventEmitter; };
这个函数启动了一个每秒钟发出一次 update
事件的事件。
第一个 if
用来检查计时是否已经结束并停止基于间隔的事件。如果已结束将会发布 end
事件。
如果计时没有结束,那么就检查计时是不是离结束还有 2 秒,如果是则发布 end-soon
事件。
向该事件发射器添加一些订阅者:
const myCountDown = countDown(5); myCountDown.on('update', (t) => { console.log(`程序已经运行了 ${t} 秒`); }); myCountDown.on('end', () => { console.log('计时结束'); }); myCountDown.on('end-soon', () => { console.log('计时将在2秒后结束'); });
这段代码将会输出:
程序已经运行了 1 秒 程序已经运行了 2 秒 程序已经运行了 3 秒 计时将在2秒后结束 程序已经运行了 4 秒 程序已经运行了 5 秒 计时结束
扩展 EventEmitter
接下来通过扩展 EventEmitter
类来实现相同的功能。首先创建一个处理事件的 CountDown
类:
const { EventEmitter } = require('events'); class CountDown extends EventEmitter { constructor(countdownTime) { super(); this.countdownTime = countdownTime; this.currentTime = 0; } startTimer() { const timer = setInterval(() => { this.currentTime++; this.emit('update', this.currentTime); // 检查计时是否已经结束 if (this.currentTime === this.countdownTime) { clearInterval(timer); this.emit('end'); } // 检查计时是否会在 2 秒后结束 if (this.currentTime === this.countdownTime - 2) { this.emit('end-soon'); } }, 1000); } }
可以在类的内部直接使用 this.emit()
。另外 startTimer()
函数用于控制计时开始的时间。否则它将在创建对象后立即开始计时。
创建一个 CountDown
的新对象并订阅它:
const myCountDown = new CountDown(5); myCountDown.on('update', (t) => { console.log(`计时开始了 ${t} 秒`); }); myCountDown.on('end', () => { console.log('计时结束'); }); myCountDown.on('end-soon', () => { console.log('计时将在2秒后结束'); }); myCountDown.startTimer();
运行程序会输出:
程序已经运行了 1 秒 程序已经运行了 2 秒 程序已经运行了 3 秒 计时将在2秒后结束 程序已经运行了 4 秒 程序已经运行了 5 秒 计时结束
on()
函数的别名是 addListener()
。看一下 end-soon
事件监听器:
myCountDown.on('end-soon', () => { console.log('计时将在2秒后结束'); });
也可以用 addListener()
来完成相同的操作,例如:
myCountDown.addListener('end-soon', () => { console.log('计时将在2秒后结束'); });
EventEmitter 的主要函数
eventNames()
此函数将以数组形式返回所有活动的侦听器名称:
const myCountDown = new CountDown(5); myCountDown.on('update', (t) => { console.log(`程序已经运行了 ${t} 秒`); }); myCountDown.on('end', () => { console.log('计时结束'); }); myCountDown.on('end-soon', () => { console.log('计时将在2秒后结束'); }); console.log(myCountDown.eventNames());
运行这段代码会输出:
[ 'update', 'end', 'end-soon' ]
如果要订阅另一个事件,例如 myCount.on('some-event', ...)
,则新事件也会添加到数组中。
这个方法不会返回已发布的事件,而是返回订阅的事件的列表。
removeListener()
这个函数可以从 EventEmitter
中删除已订阅的监听器:
const { EventEmitter } = require('events'); const emitter = new EventEmitter(); const f1 = () => { console.log('f1 被触发'); } const f2 = () => { console.log('f2 被触发'); } emitter.on('some-event', f1); emitter.on('some-event', f2); emitter.emit('some-event'); emitter.removeListener('some-event', f1); emitter.emit('some-event');
在第一个事件触发后,由于 f1
和 f2
都处于活动状态,这两个函数都将被执行。之后从 EventEmitter
中删除了 f1
。当再次发出事件时,将会只执行 f2
:
f1 被触发 f2 被触发 f2 被触发
An alias for removeListener()
is off()
. For example, we could have written:
removeListener()
的别名是 off()
。例如可以这样写:
emitter.off('some-event', f1);
removeAllListeners()
该函数用于从 EventEmitter
的所有事件中删除所有侦听器:
const { EventEmitter } = require('events'); const emitter = new EventEmitter(); const f1 = () => { console.log('f1 被触发'); } const f2 = () => { console.log('f2 被触发'); } emitter.on('some-event', f1); emitter.on('some-event', f2); emitter.emit('some-event'); emitter.removeAllListeners(); emitter.emit('some-event');
第一个 emit()
会同时触发 f1
和 f2
,因为它们当时正处于活动状态。删除它们后,emit()
函数将发出事件,但没有侦听器对此作出响应:
f1 被触发 f2 被触发
错误处理
如果要在 EventEmitter
发出错误,必须用 error
事件名来完成。这是 Node.js 中所有 EventEmitter
对象的标准配置。这个事件必须还要有一个 Error
对象。例如可以像这样发出错误事件:
myEventEmitter.emit('error', new Error('出现了一些错误'));
error
事件的侦听器都应该有一个带有一个参数的回调,用来捕获 Error
对象并处理。如果 EventEmitter
发出了 error
事件,但是没有订阅者订阅 error
事件,那么 Node.js 程序将会抛出这个 Error
。这会导致 Node.js 进程停止运行并退出程序,同时在控制台中显示这个错误的跟踪栈。
例如在 CountDown
类中,countdownTime
参数的值不能小于 2,否则会无法触发 end-soon
事件。在这种情况下应该发出一个 error
事件:
class CountDown extends EventEmitter { constructor(countdownTime) { super(); if (countdownTimer < 2) { this.emit('error', new Error('countdownTimer 的值不能小于2')); } this.countdownTime = countdownTime; this.currentTime = 0; } // ........... }
处理这个错误的方式与其他事件相同:
myCountDown.on('error', (err) => { console.error('发生错误:', err); });
始终对 error
事件进行监听是一种很专业的做法。
使用 EventEmitter 的原生模块
Node.js 中许多原生模块扩展了EventEmitter
类,因此它们本身就是事件发射器。
一个典型的例子是 Stream
类。官方文档指出:
流可以是可读的、可写的,或两者均可。所有流都是 EventEmitter
的实例。
先看一下经典的 Stream 用法:
const fs = require('fs'); const writer = fs.createWriteStream('example.txt'); for (let i = 0; i < 100; i++) { writer.write(`hello, #${i}!\n`); } writer.on('finish', () => { console.log('All writes are now complete.'); }); writer.end('This is the end\n');
但是,在写操作和 writer.end()
调用之间,我们添加了一个侦听器。 Stream
在完成后会发出一个 finished
事件。在发生错误时会发出 error
事件,把读取流通过管道传输到写入流时会发出 pipe
事件,从写入流中取消管道传输时,会发出 unpipe
事件。
另一个类是 child_process
类及其 spawn()
方法:
const { spawn } = require('child_process'); const ls = spawn('ls', ['-lh', '/usr']); ls.stdout.on('data', (data) => { console.log(`stdout: ${data}`); }); ls.stderr.on('data', (data) => { console.error(`stderr: ${data}`); }); ls.on('close', (code) => { console.log(`child process exited with code ${code}`); });
当 child_process
写入标准输出管道时,将会触发 stdout
的 data
事件。当输出流遇到错误时,将从 stderr
管道发送 data
事件。
Enfin, une fois le processus terminé, l'événement close
sera déclenché.
Résumé
L'architecture événementielle nous permet de créer des systèmes avec une cohésion élevée et un faible couplage. Un événement représente le résultat d'une action, et un ou plusieurs auditeurs peuvent être définis et y réagir.
Cet article examine en profondeur la classe EventEmitter
et ses fonctionnalités. Instanciez-le et utilisez-le directement, et étendez son comportement dans un objet personnalisé.
Enfin, quelques fonctions importantes de cette classe sont introduites.
Pour plus de connaissances liées à la programmation, veuillez visiter : Cours de programmation ! !
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.

Avec le développement de la technologie Internet, le développement front-end est devenu de plus en plus important. La popularité des appareils mobiles, en particulier, nécessite une technologie de développement frontal efficace, stable, sûre et facile à entretenir. En tant que langage de programmation en développement rapide, le langage Go est utilisé par de plus en plus de développeurs. Alors, est-il possible d’utiliser le langage Go pour le développement front-end ? Ensuite, cet article expliquera en détail comment utiliser le langage Go pour le développement front-end. Voyons d’abord pourquoi le langage Go est utilisé pour le développement front-end. Beaucoup de gens pensent que le langage Go est un

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.

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.

Golang peut être utilisé comme frontal. Golang est un langage de programmation très polyvalent qui peut être utilisé pour développer différents types d'applications, y compris des applications frontales. En utilisant Golang pour écrire le front-end, vous pouvez vous débarrasser d'un front-end. série de problèmes causés par des langages tels que JavaScript. Par exemple, des problèmes tels qu'une mauvaise sécurité des types, de faibles performances et un code difficile à maintenir.

En tant que développeur C#, notre travail de développement comprend généralement le développement front-end et back-end. À mesure que la technologie se développe et que la complexité des projets augmente, le développement collaboratif du front-end et du back-end est devenu de plus en plus important et complexe. Cet article partagera quelques techniques de développement collaboratif front-end et back-end pour aider les développeurs C# à effectuer leur travail de développement plus efficacement. Après avoir déterminé les spécifications de l’interface, le développement collaboratif du front-end et du back-end est indissociable de l’interaction des interfaces API. Pour assurer le bon déroulement du développement collaboratif front-end et back-end, le plus important est de définir de bonnes spécifications d’interface. La spécification de l'interface implique le nom de l'interface

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.

Les méthodes de mise en œuvre de la messagerie instantanée incluent WebSocket, Long Polling, Server-Sent Events, WebRTC, etc. Introduction détaillée : 1. WebSocket, qui peut établir une connexion persistante entre le client et le serveur pour obtenir une communication bidirectionnelle en temps réel. Le frontal peut utiliser l'API WebSocket pour créer une connexion WebSocket et obtenir une messagerie instantanée en envoyant et en recevant. messages 2. Long Polling, une technologie qui simule la communication en temps réel, etc.
