이 글은 주로 Nodejs 관찰자 모드 관련 정보를 소개합니다. 필요하신 분들은 참고하시면 됩니다.
1. 소개
Nodejs는 최근에 API를 검토하고 더 많은 새로운 기능을 사용해 보겠습니다. . 더 높은 수준의 숙달을 위해 이 API 요약은 영어 버전의 간단한 중국어 버전과 다릅니다. 모든 사람에게 도움이 되길 바랍니다. 핵심 Events
Nodejs 이벤트는 Nodejs의 핵심 메커니즘을 지원하는 관찰자 패턴을 구현하며, http/fs/mongoose 등은 모두 이벤트를 상속하고 청취 이벤트를 추가할 수 있습니다. 이 디자인 패턴은 클라이언트 측 구성 요소 프로그래밍 아이디어에 자주 사용됩니다. 먼저 이 패턴을 간략하게 이해하겠습니다.
내가 처음으로 관찰자 패턴을 접한 것은 Extjs 프레임워크의 Ext.util.observable 소스 코드에서였습니다. 그 당시 저는 js를 처음 접했고 이 패턴이 매우 강력하다고 느꼈습니다. 제가 접하게 된 디자인 패턴은 나중에 underscore.js 소스 코드에서도 보았습니다. 예, 저는 컴포넌트를 작성할 때 기본적으로 이 아이디어를 따릅니다.
관찰자 모드는 on('show', callback)과 같은 모니터링 이벤트를 객체에 추가하는 것인데, 이는 show와 같은 조건을 충족할 때 객체에 의해 트리거됩니다. 돔.
입력에 대한 키업 모니터링을 추가하면 해당 값을 출력하는 것이 목적입니다
$( 'input' ).on( 'keyup', function(){ console.log( this.value ); } );
이렇게 콘텐츠를 입력하면 해당 값이 로그에 출력됩니다.
하지만 Dialog와 같은 구성 요소를 만들 때 가장 일반적으로 사용되는 표시/숨기기 이벤트를 어떻게 모니터링합니까?
기본 방법은
var dialog = new Dialog({ content: '这里是弹出框的内容', show: function(){ console.log( '当弹框时输出此段内容' ); } });
과 같이 인스턴스화 중에 콜백을 직접 구성하는 것입니다. 2. 관찰자 모드 구현
먼저 기본 모니터링을 제공하는 이벤트 개체를 구현합니다. 이벤트는 json 형식입니다. 객체의 _events
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 ); } ) } } }
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 ]; } } }
만들기; 방법: 표시/숨기기;
효과를 볼 때 이 스타일을 추가하세요
.dialog{ position: fixed; top: 50%; left: 50%; margin: -50px 0 0 -100px; width: 200px; height: 120px; background: #fff; border: 5px solid #afafaf; }
var Dialog = function( config ){ this.config = config; this.init( this.config ); };
extend( Dialog.prototype, { init: function( config ){ this.render( config ) }, render: function( config ){ this.el = $( '<p>' ).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 );
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 ); } );
Dialog.show()가 실행되면 해당 로그 3개가 출력됩니다. 추가된 이벤트는 그림과 같이 Dialog._events에 저장됩니다.
추가된 세 개의 쇼는 모두 성공적으로 출력되며 이벤트는 _events 속성에 저장됩니다
nodejs Events도 이 프로세스를 구현합니다.3. 구조
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 } */
4. API
제공되는 메서드는 on이며, 이는 모두 addListener의 약어입니다. 다른 속성은 모두 인스턴스에 추가됩니다.
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 ); })
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 ? 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' );
. 6. 요약
nodejs는 매우 우수한 모니터링 메커니즘을 갖추고 있으며 nodejs의 가장 독특한 I/O 모드를 지원합니다. 연결/닫기, http.request 시 데이터/종료 등을 모니터링합니다. 모니터링 메커니즘을 이해하는 것은 nodejs의 기초를 배우고 이해하는 데 유익하며, 프로그래밍 사고를 향상시키는 데에도 도움이 됩니다.
위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되었으면 좋겠습니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요! 관련 권장 사항:Node.js에서 Buffer를 사용하여 바이너리 데이터를 인코딩 및 디코딩하는 방법
위 내용은 Nodejs 관찰자 패턴 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!