Heim Web-Frontend js-Tutorial Eine kurze Diskussion über den Nodejs-Beobachter pattern_node.js

Eine kurze Diskussion über den Nodejs-Beobachter pattern_node.js

May 16, 2016 pm 03:36 PM

1. Vorwort

Ich verwende Nodejs seit einiger Zeit. Ich werde die API überprüfen und weitere neue Funktionen verwenden, um ein höheres Maß an Beherrschung zu erreichen. Diese Zusammenfassung der API unterscheidet sich von der einfachen chinesischen Version der englischen Version . Ich werde weitere Erweiterungen vornehmen und hoffe, dass sie für alle hilfreich sind. Beginnen wir mit den Kernereignissen

Nodejs‘ Events implementiert einen Beobachtermodus, der den Kernmechanismus von Nodejs unterstützt, und http/fs/mongoose usw. erben alle Events und können Abhörereignisse hinzufügen. Dieses Entwurfsmuster wird häufig in Ideen zur clientseitigen Komponentenprogrammierung verwendet. Lassen Sie uns dieses Muster zunächst kurz verstehen.

Das erste Mal, dass ich mit dem Beobachtermuster in Kontakt kam, war im Ext.util.observable-Quellcode des Extjs-Frameworks. Ich war damals neu bei js und hatte das Gefühl, dass dieses Muster sehr leistungsfähig war Das erste Entwurfsmuster, mit dem ich in Kontakt kam, wurde später auch in den Quellcode von underscore.js aufgenommen. Da Letzteres einfacher und eleganter ist, folge ich beim Schreiben von Komponenten grundsätzlich dieser Idee.

Der Beobachtermodus besteht darin, einem Objekt ein Überwachungsereignis hinzuzufügen, z. B. on('show', callback), das vom Objekt ausgelöst wird, wenn es die Bedingungen wie show erfüllt. Der Browser selbst hat eine Überwachung implementiert Mechanismus für den Dom.

Wenn wir eine Keyup-Überwachung für die Eingabe hinzufügen, besteht der Zweck darin, den Wert auszugeben

$( 'input' ).on( 'keyup', function(){
   console.log( this.value );
} );
Nach dem Login kopieren

Wenn Sie Inhalte auf diese Weise eingeben, wird ihr Wert im Protokoll ausgegeben.

Aber wenn wir eine Komponente wie Dialog erstellen, wie können wir dann die am häufigsten verwendeten Ein-/Ausblenden-Ereignisse überwachen?

Der grundlegende Ansatz besteht darin, den Rückruf direkt während der Instanziierung zu konfigurieren, z. B.

var dialog = new Dialog({
  content: '这里是弹出框的内容',
  show: function(){
    console.log( '当弹框时输出此段内容' );
  }
});
Nach dem Login kopieren

Dies kann auch verwendet werden, ist aber offensichtlich nicht flexibel genug. Wie kann ich die dialogähnliche Eingabe gestalten und jederzeit Ereignisse hinzufügen?

2. Implementierung des Beobachtermodus

Implementieren Sie zunächst das Events-Objekt, das eine grundlegende Überwachung und Auslösung von Emitting-Ereignissen ermöglicht. Ereignisse werden in den _events des Objekts in Form von JSON gestapelt

var Events = {
  on: function( name, callback){
    this._events = this._events || {};
    this._events[ name ] = this._events[ name ] || [];
    this._events[ name ].push( callback );
  },
  emit: function( name ){
    this._events = this._events || {};
    var args = Array.prototype.slice.call( arguments, 1 ),
       me = this;
    if( this._events[ name ] ){
      $.each( this._events[ name ], function( k, v ){
        v.call( me, args );
      } )
    }
  }   
}
Nach dem Login kopieren

Eine weitere abstrakte Funktion wird zum Kopieren von Attributen für Objekte verwendet

function extend( source ){
  var args = Array.prototype.slice.call( arguments, 1 );
  for( var i = 0, parent; parent = args[i]; i++ ){
    for( var prop in parent ){
      source[ prop ] = parent[ prop ];
    }
  }
}
Nach dem Login kopieren

Implementieren Sie einen Dialog,
Implementiert nur die Erstellung; Methode: anzeigen / ausblenden; Ereignis: anzeigen / ausblenden;

Wenn Sie den Effekt sehen, fügen Sie diesen Stil hinzu

.dialog{
  position: fixed;
  top: 50%;
  left: 50%;
  margin: -50px 0 0 -100px;
  width: 200px;
  height: 120px;
  background: #fff;
  border: 5px solid #afafaf;
}
Nach dem Login kopieren
Komponenten implementieren

var Dialog = function( config ){
  this.config = config;
  this.init( this.config );
};
Nach dem Login kopieren
Erweiterte Attribute

extend( Dialog.prototype, {

  init: function( config ){
    this.render( config )
  },

  render: function( config ){
    this.el = $( '<div>' ).addClass( 'dialog' );
    this.el.html( config.content );
    $( 'body' ).append( this.el );
  },

  show: function( param ){
    this.el.fadeIn();
    this.emit( 'show', param );
  },

  hide: function( param ){
    this.el.fadeOut();
    this.emit( 'hide', param );
  }

}, Events );

Nach dem Login kopieren
Generieren Sie eine Instanz und fügen Sie ihr drei Ein- und Ausblenden-Hörereignisse hinzu

var dialog = window.dialog = new Dialog({
  content: 'dialog one'
});

dialog.on( 'show', function( txt ){
  console.log( 'dialog show one ' + txt );
} );

//do something

dialog.on( 'show', function( txt ){
  console.log( 'dialog show two ' + txt );
} );

//do something

dialog.on( 'show', function( txt ){
  console.log( 'dialog show three ' + txt );
} );

//do something

dialog.on( 'hide', function( txt ){
  console.log( 'dialog hide one ' + txt );
} );

//do something

dialog.on( 'hide', function( txt ){
  console.log( 'dialog hide two ' + txt );
} );

//do something

dialog.on( 'hide', function( txt ){
  console.log( 'dialog hide three ' + txt );
} );

Nach dem Login kopieren
Wir haben sechs verschiedene Show-Events hinzugefügt und sechs Mal Events ausgeblendet.

Wenn dialog.show() ausgeführt wird, werden drei entsprechende Protokolle ausgegeben. Die hinzugefügten Ereignisse werden in dialog._events gespeichert, wie in der Abbildung
dargestellt

Eine kurze Diskussion über den Nodejs-Beobachter pattern_node.js

Die drei hinzugefügten Shows werden alle erfolgreich ausgegeben und die Ereignisse werden im _events-Attribut gespeichert

nodejs Events implementiert diesen Prozess ebenfalls.

3. Struktur

var Events = require( 'events' );
console.log( Events );
/*
输出如下数据,可以看出 Events指向其EventEmiter
{ [Function: EventEmitter]
  EventEmitter: [Circular],
  usingDomains: [Getter/Setter],
  defaultMaxListeners: 10,
  init: [Function],
  listenerCount: [Function] }
*/

var myEmitter = new Events();
console.log( myEmitter );
/*
{ domain: null,
  _events: {},   //可以看到实例本身也有_events属性,添加的监听的事件就保存在这里
  _maxListeners: undefined}
*/

console.log( myEmitter.__proto__ );
/*
{ domain: undefined,
  _events: undefined,
  _maxListeners: undefined,
  setMaxListeners: [Function: setMaxListeners],
  emit: [Function: emit],
  addListener: [Function: addListener],
  on: [Function: addListener],
  once: [Function: once],
  removeListener: [Function: removeListener],
  removeAllListeners: [Function: removeAllListeners],
  listeners: [Function: listeners] }
*/

myEmitter.on( 'show', function( txt ){ console.log( 'one ' + txt )})
myEmitter.on( 'show', function( txt ){ console.log( 'tow ' + txt )})
myEmitter.on( 'hide', function( txt ){ console.log( 'one ' + txt )})
myEmitter.emit( 'show', 'show' );
myEmitter.setMaxListeners( 10 );
console.log( myEmitter );
/*
{ domain: null,
  _events: { show: [ [Function], [Function] ], hide: [Function] }, //添加后的事情,以json形式存放
  _maxListeners: 10 }
*/

Nach dem Login kopieren

4. API

Die bereitgestellten Methoden umfassen „on“, die Abkürzung für „addListener“. Sie fügen der Instanz alle Listening-Ereignisse hinzu

property
_events: undefined,   //以压栈形式存放on进来的事件
_maxListeners: undefined  //设置最大监听数,超出提warn

----------------------------------------------------------------------------------------------------------------

method
setMaxListeners: [Function: setMaxListeners], 
/*设置私有属性_maxListeners的值,默认Events会在当某监听事件多于10个时发现警告(见上面Events.defaultMaxListeners),以防止内存泄露,如
(node) warning: possible EventEmitter memory leak detected. 11 show listeners added. Use emitter.setMaxListeners() to increase limit.
但这只是个友好的提醒,可以通过设置最大监听数来规避这个问题
myEmitter.setMaxListeners( 20 );
*/

emit: [Function: emit],
 /*触发监听事件
emitter.emit( event, [arg1], [arg2], ... )
如myEmitter.on( 'show', 'prompt content' );
 参数1为事件名,参数二供on回调里的参数
 */

addListener: [Function: addListener],
 /*
添加监听事件
emitter.addListener( event, listener );
如 myEmitter.addListener( 'show', function( txt ){ console.log( txt ) } );
参数一是事件名,参数二是对应的回调,回调里的参数就是 emit里的arguments.prototype.slice.call(1);
 */

on: [Function: addListener],
 /*
是addListener简写
 */

once: [Function: once],
 /*
作用同 on,不过emit一次后就失效了
emitter.once( event, listener );
如 myEmitter.once( 'show', function( txt ){ console.log( txt ) } );
当myEmitter.emit执行第二次时没有输出
 */

removeListener: [Function: removeListener],
 /*
移除指定事件的指定回调,此时回调不能再用匿名函数。
emitter.removeListener( event, listener );
如 
function show( txt ){ console.log( txt ) };
myEmitter.on( 'show', show );
console.log( myEmitter._events ); 
// { show: [ Function: show ] }
myEmitter.removeListener( 'show', show );  
 console.log( myEmitter._events ); 
// {}
 */

removeAllListeners: [Function: removeAllListeners],
 /*
 删除指定事件的所有回调
 emitter.removeAllListeners( [ event ] );
 如 
  myEmitter.removeAllListeners( 'show' );   //删除所有show监听
  myEmitter.removeAllListeners();   //删除所有监听
 */

listeners: [Function: listeners]
/*
查看指定监听
emitter.listeners( event );
如 myEmitter.listeners( 'show' ); //返回一个数组
同我们前面使用的 myEmitter._events[ 'show' ]
*/

另外Events类本身提供了一个方法
Events.listenerCount( emitter, event ); 获取指定实例下指定监听数
如 Event.listenerCount( myEmitter, 'show' )

-----------------------------------------------------------------------------------------------

还有两个event
newListener / remoteListener,分别应用于为实例添加( on / once )和删除( removeListener ) 操作。
emitter.on( event, listener );
emitter.on( 'newListener', function( event, listener ){
  console.log( emitter.listeners( 'show' ) );   //注意,此时监听还并没有添加到 emitter.listeners
  console.log( arguments );  
 });

 emitter.on( 'removeListener', function(){
  console.log( emitter.listeners( 'show' ) );
  console.log( arguments );
 })

Nach dem Login kopieren
5. Bewerbung

Um Ereignisse zu verwenden, instanziieren Sie sie normalerweise einfach direkt, wie im API-Abschnitt oben gezeigt

Wenn wir jedoch auch eine Komponente auf der NodeJS-Seite implementieren, wie zum Beispiel den vorherigen Dialog, wie können wir dann dafür sorgen, dass Dialog auch die Funktion von Ereignissen hat? Erweiterungslösung, die mit Extjs implementiert werden kann

Dialog-Builder erstellen

var Dialog = function(){
  //do something
}

//抽象apply函数,提供属性的深度复制,同上面的extend
function apply( source ){
  var args = Array.prototype.slice.call( arguments, 1 );
  for( var i = 0, parent; parent = args[i]; i++ ){
    for( var prop in parent ){
      source[ prop ] = parent[ prop ];
    }
  }
}

//抽象extend函数,用于实现继承
var extend = function(){
  // inline overrides
  var io = function(o){
    for(var m in o){
      this[m] = o[m];
    }
  };
  var oc = Object.prototype.constructor;

  return function(sb, sp, overrides){
    if(typeof sp == 'object'){
      overrides = sp;
      sp = sb;
      sb = overrides.constructor != oc &#63; overrides.constructor : function(){sp.apply(this, arguments);};
    }
    var F = function(){},
      sbp,
      spp = sp.prototype;

    F.prototype = spp;
    sbp = sb.prototype = new F();
    sbp.constructor=sb;
    sb.superclass=spp;
    if(spp.constructor == oc){
      spp.constructor=sp;
    }
    sb.override = function(o){
      apply(sb, o);
    };
    sbp.superclass = sbp.supr = (function(){
      return spp;
    });
    sbp.override = io;
    apply(sb, overrides);
    sb.extend = function(o){return extend(sb, o);};
    return sb;
  };
}();

//将Events属性继承给Dialog
Dialog = extend( Dialog, Events );

//为Dialog新增 method show,其内触发 event show
Dialog.prototype.show = function( txt ){
  this.emit( 'show', txt );
}

var dialog = new Dialog();

//添加监听事件show
dialog.on( 'show', function(txt){ console.log( txt )});

//执行method show时,就会触发其内定义的show events,输出 this is show
dialog.show( 'this is show' );

Nach dem Login kopieren
Auf diese Weise wird der Ereignismechanismus für eine Komponente implementiert. Wenn die Methode aufgerufen wird, wird das Ereignis ausgelöst

6. Zusammenfassung

Nodejs bietet einen guten Überwachungsmechanismus und wird auch in allen seinen Modulen verwendet. Es unterstützt beispielsweise den charakteristischsten E/A-Modus von nodejs. Wenn wir beispielsweise den HTTP-Dienst starten, überwacht er dessen Verbindung/Schließung http.request Überwachen Sie Daten/Ende usw. Das Verständnis des Überwachungsmechanismus ist die Grundlage für das Lernen und Verstehen von NodeJS und trägt auch zur Verbesserung von Programmierideen bei.

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Was soll ich tun, wenn ich auf den Codendruck auf Kleidungsstücke für Front-End-Thermalpapier-Quittungen stoße? Apr 04, 2025 pm 02:42 PM

Häufig gestellte Fragen und Lösungen für das Ticket-Ticket-Ticket-Ticket in Front-End im Front-End-Entwicklungsdruck ist der Ticketdruck eine häufige Voraussetzung. Viele Entwickler implementieren jedoch ...

Wer bekommt mehr Python oder JavaScript bezahlt? Wer bekommt mehr Python oder JavaScript bezahlt? Apr 04, 2025 am 12:09 AM

Es gibt kein absolutes Gehalt für Python- und JavaScript -Entwickler, je nach Fähigkeiten und Branchenbedürfnissen. 1. Python kann mehr in Datenwissenschaft und maschinellem Lernen bezahlt werden. 2. JavaScript hat eine große Nachfrage in der Entwicklung von Front-End- und Full-Stack-Entwicklung, und sein Gehalt ist auch beträchtlich. 3. Einflussfaktoren umfassen Erfahrung, geografische Standort, Unternehmensgröße und spezifische Fähigkeiten.

Wie fusioniere ich Arrayelemente mit derselben ID mit JavaScript in ein Objekt? Wie fusioniere ich Arrayelemente mit derselben ID mit JavaScript in ein Objekt? Apr 04, 2025 pm 05:09 PM

Wie fusioniere ich Array -Elemente mit derselben ID in ein Objekt in JavaScript? Bei der Verarbeitung von Daten begegnen wir häufig die Notwendigkeit, dieselbe ID zu haben ...

Entmystifizieren JavaScript: Was es tut und warum es wichtig ist Entmystifizieren JavaScript: Was es tut und warum es wichtig ist Apr 09, 2025 am 12:07 AM

JavaScript ist der Eckpfeiler der modernen Webentwicklung. Zu den Hauptfunktionen gehören eine ereignisorientierte Programmierung, die Erzeugung der dynamischen Inhalte und die asynchrone Programmierung. 1) Ereignisgesteuerte Programmierung ermöglicht es Webseiten, sich dynamisch entsprechend den Benutzeroperationen zu ändern. 2) Die dynamische Inhaltsgenerierung ermöglicht die Anpassung der Seiteninhalte gemäß den Bedingungen. 3) Asynchrone Programmierung stellt sicher, dass die Benutzeroberfläche nicht blockiert ist. JavaScript wird häufig in der Webinteraktion, der einseitigen Anwendung und der serverseitigen Entwicklung verwendet, wodurch die Flexibilität der Benutzererfahrung und die plattformübergreifende Entwicklung erheblich verbessert wird.

Der Unterschied in der Konsole.log -Ausgabeergebnis: Warum unterscheiden sich die beiden Anrufe? Der Unterschied in der Konsole.log -Ausgabeergebnis: Warum unterscheiden sich die beiden Anrufe? Apr 04, 2025 pm 05:12 PM

Eingehende Diskussion der Ursachen des Unterschieds in der Konsole.log-Ausgabe. In diesem Artikel wird die Unterschiede in den Ausgabeergebnissen der Konsolenfunktion in einem Code analysiert und die Gründe dafür erläutert. � ...

TypeScript für Anfänger, Teil 2: Grundlegende Datentypen TypeScript für Anfänger, Teil 2: Grundlegende Datentypen Mar 19, 2025 am 09:10 AM

Sobald Sie das Typscript-Tutorial für Einstiegsklasse gemeistert haben, sollten Sie in der Lage sein, Ihren eigenen Code in eine IDE zu schreiben, die TypeScript unterstützt und in JavaScript zusammenfasst. Dieses Tutorial wird in verschiedenen Datentypen in TypeScript eingetaucht. JavaScript hat sieben Datentypen: NULL, UNDEFINED, BOOLEAN, NUMMER, STRING, SYMBOL (durch ES6 eingeführt) und Objekt. TypeScript definiert mehr Typen auf dieser Grundlage, und dieses Tutorial wird alle ausführlich behandelt. Null -Datentyp Wie JavaScript, null in TypeScript

Wie kann man Parallax -Scrolling- und Element -Animationseffekte wie die offizielle Website von Shiseido erzielen?
oder:
Wie können wir den Animationseffekt erzielen, der von der Seite mit der Seite mit der offiziellen Website von Shiseido begleitet wird? Wie kann man Parallax -Scrolling- und Element -Animationseffekte wie die offizielle Website von Shiseido erzielen? oder: Wie können wir den Animationseffekt erzielen, der von der Seite mit der Seite mit der offiziellen Website von Shiseido begleitet wird? Apr 04, 2025 pm 05:36 PM

Diskussion über die Realisierung von Parallaxe -Scrolling- und Elementanimationseffekten in diesem Artikel wird untersuchen, wie die offizielle Website der Shiseeido -Website (https://www.shiseeido.co.jp/sb/wonderland/) ähnlich ist ...

Kann PowerPoint JavaScript ausführen? Kann PowerPoint JavaScript ausführen? Apr 01, 2025 pm 05:17 PM

JavaScript kann in PowerPoint ausgeführt werden und durch Aufrufen externer JavaScript -Dateien oder der Einbettung von HTML -Dateien über VBA implementiert werden. 1. Um VBA zu verwenden, um JavaScript -Dateien aufzurufen, müssen Sie Makros aktivieren und VBA -Programmierkenntnisse haben. 2. Einbetten Sie HTML -Dateien ein, die JavaScript enthalten, die einfach und einfach zu bedienen sind, aber Sicherheitsbeschränkungen unterliegen. Zu den Vorteilen zählen erweiterte Funktionen und Flexibilität, während Nachteile Sicherheit, Kompatibilität und Komplexität beinhalten. In der Praxis sollte die Aufmerksamkeit auf Sicherheit, Kompatibilität, Leistung und Benutzererfahrung geschenkt werden.

See all articles