Building a simple PubSub system in JavaScript

В недавнем проекте, построенном в сервисе web push, я хотел, чтобы мой пользовательский интерфейс отвечал на события уровня приложения (семантически, если хотите), потому что было несколько компонентов, которым требуется информация от системы, но не зависят друг от друга, и я хотел, чтобы они могли управлять собой независимо от «бизнес-логики».

Я осматривал множество различных инструментов, чтобы помочь мне, но поскольку у меня часто бывает тяжелый случай синдрома NIH и тот факт, что я думаю, что люди могут быстро реализовать свои собственные инфраструктурные элементы, я решил быстро сбить простой клиент- сторона службы PubSub & mdash; он работал очень хорошо для моих нужд.

Я обсуждал, следует ли использовать пользовательское DOM Event и использовать существующую инфраструктуру, которую DOM уже предоставляет разработчикам & mdash; возможность событий и событий потребления с использованием addEventListener & mdash; но единственная проблема заключалась в том, что вы должны повесить обработчик событий из элемента DOM или окна, потому что вы не можете иметь модель, которая наследует или смешивает в «EventTarget».

_ ** Мысль: ** наличие «EventTarget» в качестве объекта поможет устранить необходимость создания пользовательских систем PubSub.

Имея в виду это ограничение, желание кодировать что-то и склонность к нежеланию ошибок, которые я создаю, я набросал приблизительный план:

/* When a user is added, do something useful (like update UI) */
EventManager.subscribe('useradded', function(user) {
  console.log(user)
});

/* The UI submits the data, lets publish the event. */
form.onsubmit(function(e) {
  e.preventDefault();

  // do something with user fields

  EventManager.publish('useradded', user);
})

Все это не ново. Redux и многие другие системы уже делают это, и во многих случаях они также помогают вам управлять состоянием. В моей голове у меня действительно нет состояния, которое нуждается в модели, которая пересекается в состояние уже в браузере.

Реализация довольно проста в реализации, и абстракция для меня очень полезна.

var EventManager = new (function() {
  var events = {};

  this.publish = function(name, data) {
    var handlers = events[name];
    if(!!handlers === false) return;
    handlers.forEach(function(handler) {
      handler.call(this, data);
    });
  };

  this.subscribe = function(name, handler) {
    var handlers = events[name];
    if(!!handlers === false) {
      handlers = events[name] = [];
    }
    handlers.push(handler);
  };

  this.unsubscribe = function(name, handler) {
    var handlers = events[name];
    if(!!handlers === false) return;

    var handlerIdx = handlers.indexOf(handler);
    handlers.splice(handlerIdx);
  };
});

Изменить: Удалено использование обещаний.

И вот мы. Простая система pubsub, которая, вероятно, полна ошибок, но мне она нравится. :) Я поместил его в github, если вас это интересует.

Paul Kinlan

Trying to make the web and developers better.

RSS Github Medium