Map
자료형을 활용하여 이벤트를 등록, 구독한다.
구독 취소의 경우 Set
자료형으로 더욱 유연하게 하시는 분들도 있던데 참고해보면 좋을듯
type Callback = (...args: any[]) => any;
type Subscription = {
unsubscribe: () => void
}
class EventEmitter {
// 이벤트 이름을 키로, 콜백 함수 배열을 값으로 가지는 Map
private events: Map<string, Callback[]> = new Map();
subscribe(eventName: string, callback: Callback): Subscription {
// 이벤트에 대한 콜백 배열이 없으면 새로 생성
if (!this.events.has(eventName)) {
this.events.set(eventName, []);
}
// 콜백 함수를 배열에 추가
this.events.get(eventName)!.push(callback);
// 구독 취소 기능을 가진 객체 반환
return {
unsubscribe: () => {
const callbacks = this.events.get(eventName);
if (callbacks) {
// 콜백 배열에서 해당 콜백 제거
const index = callbacks.indexOf(callback);
if (index !== -1) {
callbacks.splice(index, 1);
}
// 콜백이 없으면 이벤트 자체를 삭제
if (callbacks.length === 0) {
this.events.delete(eventName);
}
}
}
};
}
emit(eventName: string, args: any[] = []): any[] {
const callbacks = this.events.get(eventName);
if (!callbacks) {
return []; // 등록된 콜백이 없으면 빈 배열 반환
}
// 모든 콜백 실행 후 결과 반환
return callbacks.map(callback => callback(...args));
}
}