>웹 프론트엔드 >JS 튜토리얼 >JavaScript EventEmitter의 비밀

JavaScript EventEmitter의 비밀

亚连
亚连원래의
2018-05-28 11:21:231241검색

여기서 우리의 목표는 자체 이벤트 이미터를 만들어 그 뒤에 숨은 비밀을 이해하는 것입니다. 그럼 다음 코드가 어떻게 작동하는지 살펴보겠습니다. 필요한 친구는 이를 참조할 수 있습니다.

이벤트 이미터란 무엇인가요?

이벤트 이미터는 마치 이벤트를 트리거하는 것처럼 들립니다.

비동기 코드에서 일부 이벤트가 발생하도록 "호출"하고 다른 부분이 "호출"을 듣고 생각을 등록하도록 하는 것과 같은 시나리오를 상상해 보세요.

다양한 목적으로 이벤트 이미터 패턴을 구현하는 다양한 방법이 있지만 기본 아이디어는 이벤트 관리 및 구독 기능을 갖춘 프레임워크를 제공하는 것입니다.

여기서 우리의 목표는 자체 Event Emitter를 만들어 그 뒤에 숨은 비밀을 이해하는 것입니다. 그럼 아래 코드가 어떻게 작동하는지 살펴보겠습니다.

let input = document.querySelector("input[type="text"]");
let button = document.querySelector("button");
let h1 = document.querySelector("h1");

button.addEventListener("click", () => {
  emitter.emit("event:name-changed", { name: input.value });
});

let emitter = new EventEmitter();
emitter.subscribe("event:name-changed", data => {
  h1.innerHTML = `Your name is: ${data.name}`;
});

시작해 보세요.

class EventEmitter {
  constructor() {
    this.events = {};
  }
}

먼저 EventEmiiter 클래스를 생성하고 이벤트의 빈 객체 속성을 초기화합니다. 이 이벤트 속성의 목적은 이벤트 컬렉션을 저장하는 것입니다. 이 이벤트 개체는 이벤트 이름을 키로 사용하고 구독자 컬렉션을 값으로 사용합니다. (각 구독자를 함수로 생각할 수 있습니다).

구독 기능

subscribe(eventName, fn) {
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  }

  this.events[eventName].push(fn);
}

이 구독 기능은 이벤트 이름을 가져옵니다. 이전 예에서는 이벤트가 호출될 때 "event:name-changed" 以及传入一个回调,当有人调用 emit(또는 비명) 콜백이었습니다.

JavaScript 함수의 장점 중 하나는 다음과 같습니다. 함수는 첫 번째 개체이므로 이전 구독 방법과 마찬가지로 다른 함수의 매개 변수로 함수를 전달할 수 있습니다.

이 이벤트가 등록되지 않은 경우 처음으로 초기 값을 설정해야 합니다. 이벤트 이름은 키이고 빈 배열을 초기화하고 여기에 할당한 다음, 방출을 통해 이 이벤트를 호출하기 위해 이 배열에 함수를 넣습니다.

Call function

emit(eventName, data) {
  const event = this.events[eventName];
  if (event) {
    event.forEach(fn => {
      fn.call(null, data);
    });
  }
}

이 호출 함수는 다음을 허용합니다. 이벤트 이름, 이 이벤트 이름은 우리가 "호출"하려는 이름이고 이 이벤트에 전달하려는 데이터입니다. 이 이벤트가 이벤트에 존재하는 경우 데이터를 사용하여 구독된 모든 메서드를 반복합니다. 위의 코드는 모든 것을 할 수 있습니다. 그러나 여전히 문제가 있습니다. 더 이상 필요하지 않을 때 구독을 등록 취소할 수 있는 방법이 필요합니다. 왜냐하면 이렇게 하지 않으면 메모리 누수가 발생하기 때문입니다

이 문제를 해결하려면 구독 함수에서 등록 취소 메소드를 반환하면 됩니다.

subscribe(eventName, fn) {
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  }

  this.events[eventName].push(fn);

  return () => {
    this.events[eventName] = this.events[eventName].filter(eventFn => fn !== eventFn);
  }
}

JavaScript 함수는 첫 번째 객체이므로 함수에서 함수를 반환할 수 있으므로 이제 이 등록 취소를 호출할 수 있습니다. 함수는 다음과 같습니다.

let unsubscribe = emitter.subscribe("event:name-changed", data => console.log(data));

unsubscribe();

등록 취소 함수를 호출할 때 삭제하는 함수는 구독 함수 모음의 필터링 방법(배열 필터)에 따라 달라집니다.

메모리 누수는 안녕!

위 내용은 JavaScript EventEmitter의 비밀의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.