Last active
May 30, 2022 02:42
-
-
Save dev4design/0af8feb0d709003b1841b3b251eac1ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventBus { | |
constructor() { | |
// 이벤트 리스트 초기화 | |
this.eventObject = {}; | |
} | |
// 이벤트 발행 | |
publish(eventName) { | |
// 현재 이벤트의 모든 콜백함수 호출 | |
const callbackList = this.eventObject[eventName]; | |
if (!callbackList) return console.warn(eventName + " not found!"); | |
// 콜백함수 실행 | |
for (let callback of callbackList) { | |
callback(); | |
} | |
} | |
// 이벤트 구독 | |
subscribe(eventName, callback) { | |
// 이벤트 초기화 | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = []; | |
} | |
// 구독자가 실행할 콜백함수 저장 | |
this.eventObject[eventName].push(callback); | |
} | |
} | |
// 테스트 | |
const eventBus = new EventBus(); | |
// eventX 이벤트 구독 | |
eventBus.subscribe("eventX", () => { | |
console.log("Module A"); | |
}); | |
eventBus.subscribe("eventX", () => { | |
console.log("Module B"); | |
}); | |
eventBus.subscribe("eventX", () => { | |
console.log("Module C"); | |
}); | |
// eventX 이벤트 발행 | |
eventBus.publish("eventX"); | |
// 결과 | |
> Module A | |
> Module B | |
> Module C |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventBus { | |
constructor() { | |
this.eventObject = {}; | |
// 콜백함수 목록의 id 멤버변수 | |
this.callbackId = 0; | |
} | |
publish(eventName, ...args) { | |
const callbackObject = this.eventObject[eventName]; | |
if (!callbackObject) return console.warn(eventName + " not found!"); | |
for (let id in callbackObject) { | |
// 아이디를 가진 콜백함수 실행 | |
callbackObject[id](...args); | |
} | |
} | |
subscribe(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
// 삭제 효율을 높이기 위해 배열에서 객체 구조로 변경 | |
this.eventObject[eventName] = {}; | |
} | |
// 다음 콜백함수 사용을 위해 id를 증가 | |
const id = this.callbackId++; | |
// 아이디와 함께 콜백함수 저장 | |
this.eventObject[eventName][id] = callback; | |
// 구독 취소를 위한 내부 함수 생성 | |
const unSubscribe = () => { | |
// 이 구독자의 콜백함수 삭제 | |
delete this.eventObject[eventName][id]; | |
// 이 이벤트에 구독자가 없으면 해당 이벤트 삭제 | |
if (Object.keys(this.eventObject[eventName]).length === 0) { | |
delete this.eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
} | |
// 테스트 | |
const eventBus = new EventBus(); | |
// 구독 | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module A", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module B", obj, num); | |
}); | |
const subscriberC = eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module C", obj, num); | |
}); | |
// 발행 | |
eventBus.publish("eventX", { msg: "EventX published!" }, 1); | |
// Module C 구독 취소 | |
subscriberC.unSubscribe(); | |
// eventX 재발행. 이후부터 module C는 이벤트를 받지 않음 | |
eventBus.publish("eventX", { msg: "EventX published again!" }, 2); | |
// output | |
> Module A {msg: 'EventX published!'} 1 | |
> Module B {msg: 'EventX published!'} 1 | |
> Module C {msg: 'EventX published!'} 1 | |
> Module A {msg: 'EventX published again!'} 2 | |
> Module B {msg: 'EventX published again!'} 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventBus { | |
constructor() { | |
this.eventObject = {}; | |
this.callbackId = 0; | |
} | |
publish(eventName, ...args) { | |
const callbackObject = this.eventObject[eventName]; | |
if (!callbackObject) return console.warn(eventName + " not found!"); | |
for (let id in callbackObject) { | |
callbackObject[id](...args); | |
// 한번만 구독한 경우 해당 콜백함수를 제거 | |
if (id[0] === "d") { | |
delete callbackObject[id]; | |
} | |
} | |
} | |
subscribe(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = {}; | |
} | |
const id = this.callbackId++; | |
this.eventObject[eventName][id] = callback; | |
const unSubscribe = () => { | |
delete this.eventObject[eventName][id]; | |
if (Object.keys(this.eventObject[eventName]).length === 0) { | |
delete this.eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
// 한번만 구독을 위한 메서드 | |
subscribeOnce(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = {}; | |
} | |
// 한번만 구독할 콜백함수 마크 | |
const id = "d" + this.callbackId++; | |
this.eventObject[eventName][id] = callback; | |
const unSubscribe = () => { | |
delete this.eventObject[eventName][id]; | |
if (Object.keys(this.eventObject[eventName]).length === 0) { | |
delete this.eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
// 이벤트 제거 | |
clear(eventName) { | |
// 매개변수로 이름이 제공되지 않으면 모든 이벤트 제거 | |
if (!eventName) { | |
this.eventObject = {}; | |
return; | |
} | |
// 지정된 이름의 이벤트 제거 | |
delete this.eventObject[eventName]; | |
} | |
} | |
// 테스트 | |
const eventBus = new EventBus(); | |
// eventX 구독 | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module A", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module B", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module C", obj, num); | |
}); | |
// eventX 발행 | |
eventBus.publish("eventX", { msg: "EventX published!" }, 1); | |
// eventX 이벤트 제거 | |
eventBus.clear("eventX"); | |
// eventX 재발행. eventX에 대한 이벤트가 제거되어 모든 모듈에서 이벤트를 수신할 수 없다 | |
eventBus.publish("eventX", { msg: "EventX published again!" }, 2); | |
// output | |
> Module A {msg: 'EventX published!'} 1 | |
> Module B {msg: 'EventX published!'} 1 | |
> Module C {msg: 'EventX published!'} 1 | |
> eventX not found! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventBus { | |
constructor() { | |
this.eventObject = {}; | |
this.callbackId = 0; | |
} | |
publish(eventName, ...args) { | |
const callbackObject = this.eventObject[eventName]; | |
if (!callbackObject) return console.warn(eventName + " not found!"); | |
for (let id in callbackObject) { | |
callbackObject[id](...args); | |
// 한번만 구독한 경우 해당 콜백함수를 제거 | |
if (id[0] === "d") { | |
delete callbackObject[id]; | |
} | |
} | |
} | |
subscribe(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = {}; | |
} | |
const id = this.callbackId++; | |
this.eventObject[eventName][id] = callback; | |
const unSubscribe = () => { | |
delete this.eventObject[eventName][id]; | |
if (Object.keys(this.eventObject[eventName]).length === 0) { | |
delete this.eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
// 한번만 구독을 위한 메서드 | |
subscribeOnce(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = {}; | |
} | |
// 한번만 구독할 콜백함수 마크 | |
const id = "d" + this.callbackId++; | |
this.eventObject[eventName][id] = callback; | |
const unSubscribe = () => { | |
delete this.eventObject[eventName][id]; | |
if (Object.keys(this.eventObject[eventName]).length === 0) { | |
delete this.eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
} | |
// 테스트 | |
const eventBus = new EventBus(); | |
// eventX 구독 | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module A", obj, num); | |
}); | |
eventBus.subscribeOnce("eventX", (obj, num) => { | |
console.log("Module B", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module C", obj, num); | |
}); | |
// eventX 발행 | |
eventBus.publish("eventX", { msg: "EventX published!" }, 1); | |
// eventX 재발행. module B는 한번만 구독에 의해 콜백함수 실행되지 않음 | |
eventBus.publish("eventX", { msg: "EventX published again!" }, 2); | |
// output | |
> Module A {msg: 'EventX published!'} 1 | |
> Module C {msg: 'EventX published!'} 1 | |
> Module B {msg: 'EventX published!'} 1 | |
> Module A {msg: 'EventX published again!'} 2 | |
> Module C {msg: 'EventX published again!'} 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventBus { | |
constructor() { | |
this.eventObject = {}; | |
} | |
// 이벤트 발행: Rest 파라미터를 사용해 추가 매개변수 전달 | |
publish(eventName, ...args) { | |
const callbackList = this.eventObject[eventName]; | |
if (!callbackList) return console.warn(eventName + " not found!"); | |
for (let callback of callbackList) { | |
// 매개변수와 함께 콜백함수 실행 | |
callback(...args); | |
} | |
} | |
// 이벤트 구독 | |
subscribe(eventName, callback) { | |
if (!this.eventObject[eventName]) { | |
this.eventObject[eventName] = []; | |
} | |
this.eventObject[eventName].push(callback); | |
} | |
} | |
// 테스트 | |
const eventBus = new EventBus(); | |
// 구독 | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module A", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module B", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj, num) => { | |
console.log("Module C", obj, num); | |
}); | |
// 발행 | |
eventBus.publish("eventX", { msg: "EventX published!" }, 1); | |
// 결과 | |
> Module A {msg: 'EventX published!'} 1 | |
> Module B {msg: 'EventX published!'} 1 | |
> Module C {msg: 'EventX published!'} 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface ICallbackList { | |
[id: string]: Function; | |
} | |
interface IEventObject { | |
[eventName: string]: ICallbackList; | |
} | |
interface ISubscribe { | |
unSubscribe: () => void; | |
} | |
interface IEventBus { | |
publish<T extends any[]>(eventName: string, ...args: T): void; | |
subscribe(eventName: string, callback: Function): ISubscribe; | |
subscribeOnce(eventName: string, callback: Function): ISubscribe; | |
clear(eventName: string): void; | |
} | |
class EventBus implements IEventBus { | |
private _eventObject: IEventObject; | |
private _callbackId: number; | |
constructor() { | |
// 이벤트 리스트 초기화 | |
this._eventObject = {}; | |
// 콜백함수 목록의 id 멤버변수 | |
this._callbackId = 0; | |
} | |
// publish event | |
publish<T extends any[]>(eventName: string, ...args: T): void { | |
// 현재 이벤트의 모든 콜백함수 호출 | |
const callbackObject = this._eventObject[eventName]; | |
if (!callbackObject) return console.warn(eventName + " not found!"); | |
// 각 콜백함수 실행 | |
for (let id in callbackObject) { | |
// 매개변수와 함께 콜백함수 실행 | |
callbackObject[id](...args); | |
// 한번만 구독한 경우 해당 콜백함수를 제거 | |
if (id[0] === "d") { | |
delete callbackObject[id]; | |
} | |
} | |
} | |
// Subscribe to events | |
subscribe(eventName: string, callback: Function): ISubscribe { | |
// 이벤트 구독 | |
if (!this._eventObject[eventName]) { | |
// 삭제 효율을 높이기 위해 배열에서 객체 구조로 변경 | |
this._eventObject[eventName] = {}; | |
} | |
// 다음 콜백함수 사용을 위해 id를 증가 | |
const id = this._callbackId++; | |
// 아이디와 함께 콜백함수 저장 | |
this._eventObject[eventName][id] = callback; | |
// 구독 취소를 위한 내부 함수 생성 | |
const unSubscribe = () => { | |
// 이 구독자의 콜백함수 삭제 | |
delete this._eventObject[eventName][id]; | |
// 이 이벤트에 구독자가 없으면 해당 이벤트 삭제 | |
if (Object.keys(this._eventObject[eventName]).length === 0) { | |
delete this._eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
// 한번만 구독 | |
subscribeOnce(eventName: string, callback: Function): ISubscribe { | |
if (!this._eventObject[eventName]) { | |
this._eventObject[eventName] = {}; | |
} | |
// 한번만 구독할 콜백함수 마크 | |
const id = "d" + this._callbackId++; | |
this._eventObject[eventName][id] = callback; | |
const unSubscribe = () => { | |
delete this._eventObject[eventName][id]; | |
if (Object.keys(this._eventObject[eventName]).length === 0) { | |
delete this._eventObject[eventName]; | |
} | |
}; | |
return { unSubscribe }; | |
} | |
// 이벤트 제거 | |
clear(eventName: string): void { | |
// 매개변수로 이름이 제공되지 않으면 모든 이벤트 제거 | |
if (!eventName) { | |
this._eventObject = {}; | |
return; | |
} | |
/// 지정된 이름의 이벤트 제거 | |
delete this._eventObject[eventName]; | |
} | |
} | |
// 테스트 | |
interface IObj { | |
msg: string; | |
} | |
type PublishType = [IObj, number]; | |
const eventBus = new EventBus(); | |
// eventX 구독 | |
eventBus.subscribe("eventX", (obj: IObj, num: number, s: string) => { | |
console.log("Module A", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj: IObj, num: number) => { | |
console.log("Module B", obj, num); | |
}); | |
eventBus.subscribe("eventX", (obj: IObj, num: number) => { | |
console.log("Module C", obj, num); | |
}); | |
// eventX 발행 | |
eventBus.publish("eventX", { msg: "EventX published!" }, 1); | |
// eventX 제거 | |
eventBus.clear("eventX"); | |
// eventX 재발행. eventX에 대한 이벤트가 제거되어 모든 모듈에서 이벤트를 수신할 수 없다 | |
eventBus.publish<PublishType>("eventX", { msg: "EventX published again!" }, 2); | |
// 결과 | |
[LOG]: "Module A", { | |
"msg": "EventX published!" | |
}, 1 | |
[LOG]: "Module B", { | |
"msg": "EventX published!" | |
}, 1 | |
[LOG]: "Module C", { | |
"msg": "EventX published!" | |
}, 1 | |
[WRN]: "eventX not found!" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment