실무에서 vue를 활용한 eventbus개념을 사용허고 있었다. 이것을 broadcast라고 사용하고 있었다.
컴포넌트간의 드릴링등 여러가지의 이유가 있어서 해당개념을 사용하고 있었다.
import Vue from 'vue';
export const broadcast = new Vue();
broadcast.$emit('EVENT', message);
// on
created() {
broadcast.$on('EVENT', callback);
}
// off
beforeDestroy() {
broadcast.$off('EVENT');
}
간단하고 명료한 코드였지만, 사용하면서 조금씩의 불편함이 존재하고 있었다.
$emit
을 정확히 해야만 동작한다.$on
,$off
가 없어져서 곤란해 진다.이러한 이유 때문에 여러 사이트를 참고하여 eventbus를 만들어 보았다.
// event-bus.handler.ts
interface Subscriber {
event: ENUM;
callback: (...args: any[]) => void;
}
export interface EventBusCallback {
unsubscribe: () => void;
}
class EventBusHandler {
static instance: EventBusHandler;
static getInstance(): EventBusHandler {
if (!this.instance) {
this.instance = new EventBusHandler();
}
return this.instance;
}
private subscribers: Map<string, Subscriber> = new Map<string, Subscriber>();
private constructor() {
}
dispatch(event: ENUM, ...args: any[]) {
if (!ENUM[event]) {
console.warn(`EventBusHandler event(${event}) not found!`);
return;
}
if (!this.isExist(event)) {
console.warn(`EventBusHandler dispatch event(${event}) not found!`);
return;
}
this.subscribers.forEach((subscriber: Subscriber) => {
if (subscriber.event === event) {
subscriber.callback(...args);
}
});
}
subscribe(event: ENUM, callback: (...args: any[]) => void): EventBusCallback | null {
if (!ENUM[event]) {
console.warn(`EventBusHandler event(${event}) not found!`);
return null;
}
const id: string = this.getRandomKey();
const eventBusSubscriber: Subscriber = {
event,
callback
};
this.subscribers.set(id, eventBusSubscriber);
return {
unsubscribe: () => {
this.subscribers.delete(id);
return null;
}
};
}
private isExist(event: ENUM): boolean {
let returnValue: boolean = false;
this.subscribers.forEach((value: Subscriber) => {
if (value.event === event) {
returnValue = true;
}
});
return returnValue;
}
private getRandomKey(): string {
let result: string = '';
const characters: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const charactersLength: number = characters.length;
for (let i = 0; i < 32; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
}
export const eventBus: EventBusHandler = EventBusHandler.getInstance();
// 구독하는 곳
private subscriber: EventBusCallback | null = null;
created() {
this.subscriber = eventBus.subscribe('DEFAULT', callback);
}
beforeDestroy() {
if (!!this.subscriber) {
this.subscriber = this.subscriber.unsubscribe();
}
}
// 부르는 곳
eventBus.dispatch('DEFAULT', 'MESSAGE');
handler
부분의 코드는 확실히 증가하였으나, 프레임워크의 의존성이 더 낮아졌다고 생각한다.
프로젝트를 진행하다보면 여려가지의 이유로 의존성이 높아지는 코드들이 나오는데 차근차근 해결해 나가면 좋을거같다.