Heim  >  Artikel  >  Web-Frontend  >  Einführung in das Beobachtermuster von Nodejs

Einführung in das Beobachtermuster von Nodejs

不言
不言Original
2018-06-30 16:11:121336Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen zum Nodejs-Beobachtermodus vor.

1. Vorwort

Nodejs wurde für einige verwendet In letzter Zeit werde ich 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 und der englischen Version. Ich hoffe, es kann für alle hilfreich sein. Beginnen wir mit den Kernereignissen

Nodejs' Events implementiert einen Beobachtermodus, der den Kernmechanismus von Nodejs und http/fs/mongoose usw. unterstützt erbt Ereignisse und kann Listener-Ereignisse 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 der 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 war auch das erste Entwurfsmuster, mit dem ich in Kontakt kam. Später habe ich es in underscore.js verwendet. Es ist auch im Quellcode zu sehen, und die letztere Implementierung ist einfacher und eleganter. Ich folge dieser Idee grundsätzlich, wenn ich Komponenten schreibe.

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 dies bereits getan Implementierung des Überwachungsmechanismus für Dom.

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

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

Auf diese Weise bei der Eingabe von Inhalten , wird der Wert automatisch im Protokoll ausgegeben.

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

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( '当弹框时输出此段内容' );
  }
});

Dies kann auch verwendet werden, ist aber offensichtlich nicht flexibel genug, um den Dialog wie eine Eingabe zu gestalten und jederzeit Ereignisse hinzuzufügen?

2. Beobachtung Implementierung des Operatormusters

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 im Formular gestapelt von json

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 );
      } )
    }
  }   
}

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 ];
    }
  }
}

implementiert einen Dialog,
implementiert nur die Erstellung; Methode: anzeigen / ausblenden;

Wenn Sie sich den Effekt ansehen, 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;
}

Komponente implementieren

var Dialog = function( config ){
  this.config = config;
  this.init( this.config );
};

Erweiterte Attribute

extend( Dialog.prototype, {

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

  render: function( config ){
    this.el = $( &#39;<p>&#39; ).addClass( &#39;dialog&#39; );
    this.el.html( config.content );
    $( &#39;body&#39; ).append( this.el );
  },

  show: function( param ){
    this.el.fadeIn();
    this.emit( &#39;show&#39;, param );
  },

  hide: function( param ){
    this.el.fadeOut();
    this.emit( &#39;hide&#39;, param );
  }

}, Events );

Generieren Sie eine Instanz und fügen Sie ihr drei Ein- und Ausblenden-Ereignisse hinzu.

var dialog = window.dialog = new Dialog({
  content: &#39;dialog one&#39;
});

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

//do something

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

//do something

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

//do something

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

//do something

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

//do something

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

Wir haben sechs verschiedene Ein- und Ausblenden-Ereignisse in sechs Malen hinzugefügt.
Wenn dialog.show() ausgeführt wird, werden drei entsprechende Protokolle ausgegeben. Die hinzugefügten Ereignisse werden in dialog._events gespeichert, wie in der Abbildung gezeigt

Einführung in das Beobachtermuster von Nodejs

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

nodejs Events implementiert diesen Prozess ebenfalls.

3. Struktur

var Events = require( &#39;events&#39; );
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( &#39;show&#39;, function( txt ){ console.log( &#39;one &#39; + txt )})
myEmitter.on( &#39;show&#39;, function( txt ){ console.log( &#39;tow &#39; + txt )})
myEmitter.on( &#39;hide&#39;, function( txt ){ console.log( &#39;one &#39; + txt )})
myEmitter.emit( &#39;show&#39;, &#39;show&#39; );
myEmitter.setMaxListeners( 10 );
console.log( myEmitter );
/*
{ domain: null,
  _events: { show: [ [Function], [Function] ], hide: [Function] }, //添加后的事情,以json形式存放
  _maxListeners: 10 }
*/

4. API

Es Zu den bereitgestellten Methoden gehört on, die Abkürzung für addListener. Sie fügen der Instanz alle Listening-Ereignisse hinzu

5. Anwendung

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

Wenn wir jedoch auch eine Komponente auf der NodeJS-Seite implementieren, z. B. die vorheriger Dialog, wie man den Dialog erstellt Hat er auch die Funktion von Ereignissen? Die Erweiterungslösung, die mit Extjs implementiert werden kann

Dialog-Builder erstellen

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( &#39;show&#39;, &#39;prompt content&#39; );
 参数1为事件名,参数二供on回调里的参数
 */

addListener: [Function: addListener],
 /*
添加监听事件
emitter.addListener( event, listener );
如 myEmitter.addListener( &#39;show&#39;, 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( &#39;show&#39;, function( txt ){ console.log( txt ) } );
当myEmitter.emit执行第二次时没有输出
 */

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

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

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

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

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

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

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

Auf diese Weise wird der Ereignismechanismus für eine Komponente implementiert . Wenn die Methode aufgerufen wird, wird ein Ereignis ausgelöst

6. Zusammenfassung

nodejs bietet einen guten Überwachungsmechanismus und wird auch auf alle seine Module angewendet. Es unterstützt die meisten Im I-Modus von nodejs./O überwachen wir beispielsweise beim Starten des HTTP-Dienstes dessen Verbindung/Schließung, bei http.request überwachen wir die Daten/Ende usw. Das Verständnis des Überwachungsmechanismus ist die Grundlage für das Lernen und Verständnis von NodeJS und ist auch hilfreich bei der Verbesserung von Programmierideen.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website. Verwandte Empfehlungen:

So verwenden Sie Buffer zum Kodieren und Dekodieren von Binärdaten in Node.js

Grundsyntax von NodeJs und Einführung von Typen


Das obige ist der detaillierte Inhalt vonEinführung in das Beobachtermuster von Nodejs. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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