node 의 사건 메커니즘 에 대하 여 논 하 다.

Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient.
nodejs 의 공식 문서 에 node 의 특성 중 하 나 는 이벤트-driven(이벤트 구동)이 라 고 명확 하 게 적 혀 있 는 것 을 보면 매우 중요 하 다.원본 코드 를 보면,우 리 는 그 이벤트 메커니즘 이 js 로 쓴 EventEmitter 클래스 로 매우 우아 하 게 쓰 여 졌 고,게시/구독 모드 를 응용 했다 는 것 을 알 수 있다.
간단 하고 발표/구독 모델 을 가 진 이벤트 체 제 를 실현 함으로써 EventEmitter 류 의 실현 방향 을 정리 합 니 다.
게시/구독(게시/구독 모드)
비교 하 다
말 하고 자 하 는 것 은 하나의 모델 이다.모델 이라는 단 어 는 듣 기 에 매우 추상 적 이다.우리 먼저 밤 을 들 자.신문 기구 가 있다 고 가정 하면 아침 신문,오보,석간신문 을 제공한다.만약 당신 이 어떤 신문 을 보고 싶다 면,당신 은 신문 기구 에 구독 해 야 합 니 다.해당 신문 이 발표 되면,신문 기 구 는 당신 에 게 신문 을 가 져 오 라 고 통지 할 것 입 니 다.
이 과정 에서 신문 기 구 는 두 가지 기능 을 실현 했다.하 나 는 고객 의 구독 을 받 는 것 이다.둘 째 는 서로 다른 유형의 신문 을 발표 하 는 것 이다.신문 을 발표 할 때 이 유형의 신문 을 구독 하 는 고객 은 통 지 를 받 을 수 있다.
이 신문 기 구 는 바로 우리 가 실현 해 야 할 사건 체제 이다.

목적.
위의 예 를 통 해 알 수 있 듯 이 1.신문 을 발표 합 니 다.2.고객 에 게 신문 을 전달 합 니 다.이 연속 적 인 과정 은 신문 기구의 존재 로 인해 먼저 구독 하고 발표 할 수 있 게 되 었 고 발표 되면 자동 으로 고객 에 게 전달 되 어 동작 시간의 분 리 를 실현 했다.이것 도 게시/구독 시스템 의 장점 이다.
사고의 방향 을 실현 하 다.
우 리 는 세 가지 신문 이 있 는데,세 가지 사건 에 대응 하여,모든 사건 이 발생 할 때 고객 에 게 통지 해 야 한다.대응 하 는 데이터 형식 은 다음 과 같 습 니 다.

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)

node 의 EventEmitter
node 의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.발표 이벤트

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 의 실현 방향 을 잘 알 고 계 실 거 라 고 믿 습 니 다.
참고 자료
node events.js
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기