Проста реалізація Event Bus на JavaScript

4 хв. читання

Event Bus є надзвичайно корисним інструментом, який дозволяє зробити компоненти у ваших застосунках незалежними один від одного. У використанні Event Bus є свої плюси та мінуси, які потрібно врахувати при реалізації, щоб надалі зберегти простий та зрозумілий код.

Але, без сумніву, Event Bus може значно пришвидшити реалізацію, а також спростити архітектуру ваших застосунків.

У цій статті, я хочу показати, як реалізувати простий Event Bus у JavaScript.

Що таке Event Bus?

Event Bus — реалізація популярного шаблону publisher/subscriber (видавець/підписник). Він може бути використаний для відокремлення окремих компонентів в рамках одного застосунку. Таким чином, будь-який компонент може реагувати на будь-яку подію без додаткового зв'язку з іншими компонентами. Необхідно просто бути підписаним на Event Bus.

Кожен subscriber може підписатись на конкретну подію. Після спрацювання цієї події, всі її підписники будуть сповіщені про це. У свою чергу publisher може публікувати події в Event Bus, чим запустить раніше створені підписки.

Реалізація Event Bus

У даній реалізації підписник є функцією. Зв'язок між подією та функціями, які до неї відносяться, реалізовано об'єктом EventCallbacksPair:

function EventCallbacksPair( eventType, callback ) {
    this.eventType = eventType;
    this.callbacks = [ callback ];
}

Наш Event Bus буде містити список об'єктів EventCallbacksPair (по одному на кожну подію). Події можуть бути будь-якого типу. Зазвичай використовується string, але це не єдиний варіант.

Subscribe:

Кожен раз, коли підписник хоче підписатись на подію, може виникнути два наступних варіанти:

  1. Ніхто раніше ще не підписувався на цю подію, тому Event Bus не містить EventCallbacksPair для цього об'єкту.
  2. У даної події вже є підписники, тому Event Bus вже містить об'єкт EventCallbacksPair з потрібною подією.

У першому випадку нам потрібно створити новий об'єкт типу EventCallbacksPair і додати у список Event Bus. В другому випадку ми просто додаємо необхідну подію до вже наявного об'єкта в поле callbacks.

this.subscribe = function( eventType, callback ) {
  const eventCallbacksPair = findEventCallbacksPair( eventType );
  if(eventCallbacksPair)
    eventCallbacksPair.callbacks.push( callback );
  else
    eventCallbacksPairs
      .push( new EventCallbacksPair( eventType, callback ) );
}

Publish:

Коли в Event Bus публікується нова подія, можуть виникнути наступні варіанти:

  1. Event Bus містить EventCallbacksPair для цієї події.
  2. У нашому списку відсутні підписки на цю подію.

У першому випадку ми знаходимо EventCallbacksPair і викликаємо всі функції зворотного виклику, які є в нього, в полі callbacks. В іншому випадку просто повідомляємо, що будь-які підписки на цю подію відсутні.

this.post = function( eventType ) {
  const eventCallbacksPair = findEventCallbacksPair( eventType );
  if( !eventCallbacksPair ) {
    console.error("no subscribers for event " + eventType);
    return;
  }
  eventCallbacksPair.callbacks.forEach( callback => callback() );
}

Фінальна реалізація:

Повна реалізація простого Event Bus. Також цей код можна знайти тут.

function EventBus() {
    const eventCallbacksPairs = [];
    
    this.subscribe = function( eventType, callback ) {
        const eventCallbacksPair = findEventCallbacksPair(eventType);

        if(eventCallbacksPair)
            eventCallbacksPair.callbacks.push(callback);
        else
            eventCallbacksPairs.push( new EventCallbacksPair(eventType, callback) );
    }

    this.post = function( eventType, args ) {
        const eventCallbacksPair = findEventCallbacksPair(eventType);
        
        if(!eventCallbacksPair) {
            console.error("no subscribers for event " +eventType);
            return;
        }

        eventCallbacksPair.callbacks.forEach( callback => callback(args) );
    }

    function findEventCallbacksPair(eventType) {
        return eventCallbacksPairs.find( eventObject => eventObject.eventType === eventType );
    }

    function EventCallbacksPair( eventType, callback ) {
        this.eventType = eventType;
        this.callbacks = [callback];
    }
}
Помітили помилку? Повідомте автору, для цього достатньо виділити текст з помилкою та натиснути Ctrl+Enter
Codeguida 5.6K
Приєднався: 8 місяців тому
Коментарі (0)

    Ще немає коментарів

Щоб залишити коментар необхідно авторизуватися.

Вхід / Реєстрація