Maison > interface Web > js tutoriel > le corps du texte

Explication du mécanisme d'événement de nœud

小云云
Libérer: 2018-01-26 13:31:34
original
1443 Les gens l'ont consulté

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
}
Copier après la connexion

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
}
Copier après la connexion

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(&#39;console1&#39;, function(num) {
 console.log(num); // 1
});

Event.emit(&#39;console1&#39;, 1)
Copier après la connexion

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 !== &#39;function&#39;)
  throw new TypeError(&#39;"listener" argument must be a function&#39;);

 events = target._events;
 ...
 if (typeof existing === &#39;function&#39;) {
   // Adding the second element, need to change to array.
   existing = events[type] =
    prepend ? [listener, existing] : [existing, listener];
  } else {
   // If we&#39;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;
Copier après la connexion

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);
 }
}
Copier après la connexion

À 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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!