이 글은 주로 노드의 이벤트 메커니즘을 소개합니다. 이 글은 EventEmitter 클래스의 구현 아이디어를 명확히 하기 위해 게시/구독 모드로 간단한 이벤트 메커니즘을 구현합니다.
Node.js는 이벤트 중심의 비차단 I/O 모델을 사용하여 가볍고 효율적입니다.
nodejs의 공식 문서에는 노드의 기능 중 하나가 이벤트라고 명시되어 있습니다. Driven(이벤트 드라이버)이 매우 중요하다는 것을 알 수 있습니다. 소스 코드를 보면 이벤트 메커니즘이 js로 작성된 EventEmitter 클래스라는 것을 알 수 있습니다. 이는 매우 우아하게 작성되었으며 발행/구독 모델을 적용합니다.
게시/구독 모드로 간단한 이벤트 메커니즘을 구현함으로써 EventEmitter 클래스의 구현 아이디어를 명확하게 할 수 있습니다.
게시/구독(게시/구독 모드)
비유
는 패턴이라는 단어에 대한 것입니다. , 매우 추상적으로 들립니다. 먼저 밤을 드리자. 아침, 점심, 저녁 신문을 제공하는 신문사가 있다고 가정해 보겠습니다. 특정 신문을 읽으려면 신문사에 가입해야 합니다. 해당 신문이 발행되면 신문사에서 신문을 가져오라고 알려줍니다.
이 과정에서 신문사는 두 가지 기능을 구현했습니다. 하나는 고객 구독을 받아들이는 것이고, 다른 하나는 다양한 유형의 신문을 발행하는 것입니다. 신문이 발행되면 해당 신문을 구독하는 고객에게 알림이 전송됩니다.
이 신문 조직은 우리가 구현하려는 이벤트 메커니즘입니다.
목적
위의 예에서 볼 수 있듯이: 1. 신문을 발행합니다. 2. 신문 조직이 있기 때문에 이 지속적인 프로세스를 먼저 구독할 수 있습니다. 출시되면 자동으로 고객에게 전송되어 작업 시간의 분리를 실현합니다. 이는 발행/구독 시스템의 장점이기도 합니다.
구현 아이디어
3가지 종류의 신문이 있고, 3가지 이벤트에 해당하며, 각 이벤트가 발생할 때 고객에게 알려야 합니다. 해당 데이터 형식은 다음과 같습니다.
var Event = { morning: event1, noon: event2, night: event3 }
각 신문은 두 명 이상의 사람이 구독할 수 있으므로 형식은 다음과 같이 최적화될 수 있습니다.
var Event = { morning: [e11, e12,...], noon: [e21, e22], night: event3 }
사용자가 구독하면 우리는 이벤트는 해당 배열에 추가되며, 이벤트가 해제되면 해당 이벤트가 실행됩니다. 직설적으로 말하면 먼저 보관하고 사용하십시오.
구체적인 코드는 다음과 같습니다.
1.on은 구독, 해당 배열에 이벤트 추가를 의미합니다.
2.emit은 게시, 실행을 위해 해당 배열의 데이터를 꺼내는 것을 의미합니다.
3.off는 쓸모 없는 이벤트를 삭제하는 것을 의미합니다.
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
노드 EventEmitter의 기본 로직은 기본적으로 위에 제공된 예제와 동일하지만 더 복잡합니다.
1.
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에서 이벤트를 구독하세요. 2. 이벤트 게시
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); } }
이렇게 말하면 모두가 EventEmitter의 구현 아이디어를 이해했다고 믿습니다.
관련 권장 사항:
위 내용은 노드 이벤트 메커니즘 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!