この解答例はChatGPTによって生成されています,正しいかは自己判断で。 皆の投稿からも解答例が見つかるかもしれませんよ。

BFE.devでのAI解答例 - JavaScript コーディング問題
71. Observable Subjectを実装する

class Subject {  constructor() {    this.observers = [];  }  subscribe(observer) {    this.observers.push(observer);  }  unsubscribe(observer) {    this.observers = this.observers.filter((obs) => obs !== observer);  }  next(value) {    for (let observer of this.observers) {      if (observer.next) {        observer.next(value);      } else if (typeof observer === 'function') {        observer(value);      }    }  }  error(error) {    for (let observer of this.observers) {      if (observer.error) {        observer.error(error);      }    }  }  complete() {    for (let observer of this.observers) {      if (observer.complete) {        observer.complete();      }    }  }}

このSubjectは、ObservableSubjectとして振る舞います。すべてのSubscriptionまたはObserverに同じ値を渡します。SubscriptionやObserverはadd和removeによって変更でき、受け取った値が同期されます。Subjectの内部にあるobservers配列に登録されたobserverのリストがあります。

各メソッドでobservers配列上で繰り返し、SubscriberまたはObserverの値を遅延コールバックで呼び出します。 next,error、さらにcompleteのように、ObservableSubjectを完了すると、新しい値またはエラーが投げられたときに、Subscriptionを解除することができます。

例えば、以下のように使うことができます。

const subject = new Subject();const observer1 = {  next: (value) => console.log(value * 2),};const observer2 = (value) => console.log(value + 2);subject.subscribe(observer1);subject.subscribe(observer2);subject.next(3);subject.complete();// 6// 5

observerの一つはmethodとして、もう一つはfunctionとして登録されています。.nextメソッドは遅延呼び出しになります、つまり、3が後から通知されることを意味します。最後の.complete()はSubscriptionを削除することを意味します。

注意してください、SubjectはObserverもしくはObservableの観察対象であり、自己実行するObserverではありません。 したがって、必ずしも初期化時に値を渡す必要はありません。

このように、Subjectを使用することで、Observableに複数の制御フローを追加できます。あなたは、Observableとともに、addやremove、もっと多くのカスタマイズを一緒に持つことができます。