Panda Noir

JavaScript の限界を究めるブログでした。最近はいろんな分野を幅広めに書いてます。

pubsub パターンの現時点でのベストプラクティス

以前pubsub パターンのベタープラクティスを考えたんですが、よく考えたらイベント名を設定する必要なかったです。

これでよさそう↓

class PubSub<Payload extends unknown[]> {
  private listeners: ((...payload: Payload) => void)[] = [];
  subscribe(callback: (...payload: Payload) => void) {
    this.listeners.push(callback);
  }
  unsubscribe(callback: (...payload: Payload) => void) {
    this.listeners = this.listeners.filter((item) => item !== callback);
  }
  publish(...payload: Payload) {
    for (const listener of this.listeners) {
      listener(...payload);
    }
  }
}

export const buttonPubsub = new PubSub<[]>();
export const messagePubsub = new PubSub<[string]>();

イベント名を指定したかったらオーバーロードを使えば実装可能

const subscribe: {
  (eventName: 'click', callback: () => void): void;
  (eventName: 'message', callback: (message: string) => void): void;
} = (eventName: string, callback: (...event: any[]) => void) => {
  switch (eventName) {
    case 'click':
      buttonPubsub.subscribe(callback);
      break;
    case 'message':
      messagePubsub.subscribe(callback);
      break;
  }
};
subscribe('message', (mes: string) => console.log(mes)); // OK
subscribe('click', (mes: string) => console.log(mes)); // 型エラー