この解答例はChatGPTによって生成されています,正しいかは自己判断で。

BFE.devでのAI解答例 - JavaScript コーディング問題
57. Observableを作る

以下が求められているObservableの実装例です。

class Observable {
  constructor(subscribeFunc) {
    this._subscribe = subscribeFunc;
  }

  subscribe(observerOrNext, error, complete) {
    // if observerOrNext is an observer object
    if (typeof observerOrNext === 'object') {
      return this._subscribe(observerOrNext);
    }

    // if observerOrNext is a function
    return this._subscribe({
      next: observerOrNext,
      error: error,
      complete: complete
    });
  }

  // helper method to create observable from iterable
  static from(iterable) {
    return new Observable(subscriber => {
      for (const item of iterable) {
        subscriber.next(item);
      }
      subscriber.complete();
    });
  }

  // helper method to create observable from a promise
  static fromPromise(promise) {
    return new Observable(subscriber => {
      promise.then(
        value => {
          subscriber.next(value);
          subscriber.complete();
        },
        reason => subscriber.error(reason)
      );
    });
  }

  // helper method to create observable from an event
  static fromEvent(target, eventName) {
    return new Observable(subscriber => {
      const eventHandler = e => subscriber.next(e);
      target.addEventListener(eventName, eventHandler);

      // return cleanup function
      return () => {
        target.removeEventListener(eventName, eventHandler);
      };
    });
  }

  // helper method to merge multiple observables
  static merge(...observables) {
    return new Observable(subscriber => {
      let activeSubscriptions = observables.length;

      const subscriptions = observables.map(obs =>
        obs.subscribe({
          next: value => subscriber.next(value),
          error: error => subscriber.error(error),
          complete: () => {
            activeSubscriptions--;
            if (activeSubscriptions === 0) {
              subscriber.complete();
            }
          }
        })
      );

      // return cleanup function
      return () => {
        subscriptions.forEach(sub => sub.unsubscribe());
      };
    });
  }
}

この実装では、subscribe()メソッドの引数として、Observerオブジェクトか、next/error/completeのいずれかを含む関数を受け取り、両方の型の引数を同じように処理できます。また、from()、fromPromise()、fromEvent()、merge()といったヘルパーメソッドを持っており、Observableインスタンスを作りやすくなっています。