Maison > Article > interface Web > Explication du mécanisme d'événement de nœud
Cet article présente principalement le mécanisme d'événement de node. Cet article implémente un mécanisme d'événement simple avec mode publication/abonnement pour clarifier les idées d'implémentation de la classe EventEmitter. Ceux qui sont intéressés pourront en apprendre davantage. Tout le monde.
Node.js utilise un modèle d'E/S non bloquant et piloté par les événements qui le rend léger et efficace.
Dans la documentation officielle de nodejs, il est clairement écrit L'une des fonctionnalités de node est pilotée par les événements, ce qui montre qu'elle est très importante. En regardant le code source, nous pouvons voir que son mécanisme d'événement est la classe EventEmitter écrite en js, qui est écrite de manière très élégante et applique le modèle de publication/abonnement.
En implémentant un mécanisme d'événement simple avec le mode publication/abonnement, nous pouvons clarifier les idées d'implémentation de la classe EventEmitter
Publish/Subscribe (mode publication/abonnement)
L'analogie
concerne un modèle, et le mot modèle semble très abstrait. Donnons d’abord une châtaigne. Supposons qu'il existe une organisation de presse qui propose des journaux du matin, de l'après-midi et du soir. Si vous souhaitez lire un certain journal, vous devez vous abonner à l'organisation du journal. Lorsque le journal correspondant sera publié, l'organisation du journal vous demandera de récupérer le journal.
Dans ce processus, l'organisation du journal met en œuvre deux fonctions, l'une consiste à accepter les abonnements des clients ; l'autre est de publier différents types de journaux. Lorsqu'un journal est publié, les clients abonnés à ce type de journal recevront des notifications.
Cette organisation de journal est le mécanisme événementiel que nous souhaitons mettre en place.
Objectif
Comme le montre l'exemple ci-dessus : 1. Publier le journal 2. Donner le journal au ; client ; ceci En raison de l'existence de l'organisation du journal, le processus continu peut d'abord être souscrit puis publié lorsqu'il est publié, il sera automatiquement envoyé au client, réalisant ainsi la séparation du temps d'action. C’est aussi l’avantage des systèmes de publication/abonnement.
Idées de mise en œuvre
Nous avons 3 types de journaux, correspondant à 3 événements, et les clients doivent être avertis lorsque chaque événement se produit. Le format de données correspondant peut être le suivant :
var Event = { morning: event1, noon: event2, night: event3 }
Comme chaque journal peut être abonné par plus d'une personne, le format peut être optimisé comme ceci :
var Event = { morning: [e11, e12,...], noon: [e21, e22], night: event3 }
Lorsqu'un utilisateur s'abonne, on ajoute son événement au tableau correspondant ; lorsque l'événement est publié, l'événement correspondant est exécuté. Pour parler franchement, stockez-le d’abord, puis utilisez-le.
Le code spécifique est le suivant :
1.on signifie s'abonner, ajouter l'événement au tableau correspondant
2.emit signifie publier, ajouter les données dans le tableau correspondant Retirez-le et exécutez
3.off pour supprimer les événements inutiles
var Event = { on: function(key, listener) { if (!this.__events) { this.__events = {} } if (!this.__events[key]) { this.__events[key] = []; } if (_indexOf(this.__events[key], listener) == -1 && typeof listener === 'function') { this.__events[key].push(listener) } }, emit: function(key) { if (!this.__events || !this.__events[key]) return //取得每次订阅不同的参数 var arg = Array.prototype.slice.call(arguments, 1) || []; var listeners = this.__events[key]; var len = listeners.length; for (var i=0; i<len; i++) { listeners[i].apply(this, arg) } return this }, off: function(key, listener) { if (!key && !listener) { this.__events = {} } if (key && !listener) { delete this.__events[key] } if (key && listener) { var listeners = this.__events[key]; var index = _indexOf(listeners, listener); (index > -1) && listeners.splice(index, 1); } return this } } var _indexOf = function(array,key){ if (array === null) return -1 var i = 0, length = array.length for (; i < length; i++) if (array[i] === key) return i return -1 } //调用 Event.on('console1', function(num) { console.log(num); // 1 }); Event.emit('console1', 1)
EventEmitter of node
EventEmitter of node La logique de base est fondamentalement la même que celle de l'exemple fourni ci-dessus, juste plus compliquée.
1. Abonnez-vous aux événements sur
function _addListener(target, type, listener, prepend) { var m; var events; var existing; if (typeof listener !== 'function') throw new TypeError('"listener" argument must be a function'); events = target._events; ... if (typeof existing === 'function') { // Adding the second element, need to change to array. existing = events[type] = prepend ? [listener, existing] : [existing, listener]; } else { // If we've already got an array, just append. if (prepend) { existing.unshift(listener); } else { existing.push(listener); } } return target; } EventEmitter.prototype.addListener = function addListener(type, listener) { return _addListener(this, type, listener, false); }; EventEmitter.prototype.on = EventEmitter.prototype.addListener;
2. Publier des événements
EventEmitter.prototype.emit = function emit(type) { ... handler = events[type]; switch (len) { // fast cases case 1: emitNone(handler, isFn, this); break; case 2: emitOne(handler, isFn, this, arguments[1]); break; case 3: emitTwo(handler, isFn, this, arguments[1], arguments[2]); break; case 4: emitThree(handler, isFn, this, arguments[1], arguments[2], arguments[3]); break; // slower default: args = new Array(len - 1); for (i = 1; i < len; i++) args[i - 1] = arguments[i]; emitMany(handler, isFn, this, args); } }
À ce stade, je pense que tout le monde comprend déjà l'idée de mise en œuvre d'EventEmitter.
Recommandations associées :
Mise en œuvre du mécanisme d'événement PHP
Mécanisme d'événement et blocage en jq et js
Mécanisme d'événements JavaScript
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!