[RxJS in Angular]- サブジェクト分類の紹介

        RxJS のサブジェクトは、値を複数のオブザーバーにマルチキャストできる特別なタイプの Observable であるため、サブジェクトはマルチキャストですが、通常の Observable はユニキャストです (サブスクライブされた各オブザーバーには、個別に実行される Observable があります)。

        コードでの定義:        

export declare class Subject<T> extends Observable<T> implements SubscriptionLike {}

        RxJS で一般的に使用される Subject には、通常の Subject、BehaviorSubject、AsyncSubject、ReplaySubject の 4 種類があります。

普通Subject

        一般的な件名の例:

    let subject: Subject<number> = new Subject<number>();
    
    let count = 0;
    let intervalId = setInterval(() => {
      count++;
      if (count < 3) {
        subject.next(count);
      } else {
        subject.complete();
        clearInterval(intervalId);
      }
    }, 1000);

    subject.subscribe(
      data => { console.log(`1st subscribe: ${data}`) },
      (err) => { console.log(`1st subscribe err: ${err}`) },
      () => { console.log(`1st subscribe complete`) });

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`2nd subscribe: ${data}`) },
        (err) => { console.log(`2nd subscribe err: ${err}`) },
        () => { console.log(`2nd subscribe complete`) });
    }, 2000);

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`3rd subscribe: ${data}`) },
        (err) => { console.log(`3rd subscribe err: ${err}`) },
        () => { console.log(`3rd subscribe complete`) });
    }, 5000);

        操作結果:

         効果は Hot Observables と同じであることがわかります.値が発行された後に追加されたサブスクリプションは、値とその前に発行された値を受け取ることができません. ただし、完了通知を受け取ることはできます。したがって、Subject は Hot Observable です。

行動主体

        サブジェクトの 1 つのバリアントは、「現在の値」の概念を持つ BehaviorSubject です。コンシューマーに送信された最新の値を保持します。そして、新しいオブザーバーがサブスクライブすると、すぐに BehaviorSubject から「現在の値」を受け取ります。

    let subject: BehaviorSubject<number> = new BehaviorSubject<number>(0);

    let count = 0;
    let intervalId = setInterval(() => {
      count++;
      if (count < 3) {
        subject.next(count);
      } else {
        subject.complete();
        clearInterval(intervalId);
      }
    }, 1000);

    subject.subscribe(
      data => { console.log(`1st subscribe: ${data}`) },
      (err) => { console.log(`1st subscribe err: ${err}`) },
      () => { console.log(`1st subscribe complete`) });

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`2nd subscribe: ${data}`) },
        (err) => { console.log(`2nd subscribe err: ${err}`) },
        () => { console.log(`2nd subscribe complete`) });
    }, 2100);

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`3rd subscribe: ${data}`) },
        (err) => { console.log(`3rd subscribe err: ${err}`) },
        () => { console.log(`3rd subscribe complete`) });
    }, 5000);

        操作結果:

        本体が 2 を送信し、値 2 (「現在の値」) を受信した後、2 番目のサブスクリプションが追加されていることがわかります。

        一般的なサブジェクトとの違いをよりよく反映するために、サブジェクトがデータ プッシュを完了していないと考えて、上記のコードの subject.complete(); をコメント アウトすることができます。

        この時点で、一般的な Subject の実行結果を使用します。        

        2回目、3回目の定期購読追加後、本体からデータが送られてこないので印刷されません。

        BehaviorSubject を使用した結果:

         2 番目と 3 番目のサブスクリプションが追加された後、本体はデータを送信していませんが、両方とも本体の現在の値 (最後に送信されたデータ) を受信して​​いるため、すべて 2 が出力されます。

リプレイ件名

        ReplaySubject は、古い値を新しいサブスクライバーに送信できるという点で BehaviorSubject に似ていますが、Observable の実行の一部を記録することもできます。

    let subject: ReplaySubject<number> = new ReplaySubject<number>(2);
    
    let count = 0;
    let intervalId = setInterval(() => {
      count++;
      if (count < 5) {
        subject.next(count);
      } else {
        subject.complete();
        clearInterval(intervalId);
      }
    }, 1000);

    subject.subscribe(
      data => { console.log(`1st subscribe: ${data}`) },
      (err) => { console.log(`1st subscribe err: ${err}`) },
      () => { console.log(`1st subscribe complete`) });

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`2nd subscribe: ${data}`) },
        (err) => { console.log(`2nd subscribe err: ${err}`) },
        () => { console.log(`2nd subscribe complete`) });
    }, 4000);

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`3rd subscribe: ${data}`) },
        (err) => { console.log(`3rd subscribe err: ${err}`) },
        () => { console.log(`3rd subscribe complete`) });
    }, 8000);

        操作結果:

         後で追加されたサブスクリプションは、最近開始された 2 つのデータ値を受け取り、完了の通知を受け取っていることがわかります。

AsyncSubject

        AsyncSubject は、Observable の実行が完了する (complete() を実行する) ときに、実行の最後の値のみをオブザーバーに送信するもう 1 つの Subject バリアントです。

    let subject: AsyncSubject<number> = new AsyncSubject<number>();

    let count = 0;
    let intervalId = setInterval(() => {
      count++;
      if (count < 5) {
        subject.next(count);
      } else {
        subject.complete();
        clearInterval(intervalId);
      }
    }, 1000);

    subject.subscribe(
      data => { console.log(`1st subscribe: ${data}`) },
      (err) => { console.log(`1st subscribe err: ${err}`) },
      () => { console.log(`1st subscribe complete`) });


    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`2nd subscribe: ${data}`) },
        (err) => { console.log(`2nd subscribe err: ${err}`) },
        () => { console.log(`2nd subscribe complete`) });
    }, 3000);

    setTimeout(() => {
      subject.subscribe(
        data => { console.log(`3rd subscribe: ${data}`) },
        (err) => { console.log(`3rd subscribe err: ${err}`) },
        () => { console.log(`3rd subscribe complete`) });
    }, 6000);

        操作結果:

        すべてのサブスクリプションは、本体が完了する前に送信された最後のデータのみを受信したことがわかります。 

おすすめ

転載: blog.csdn.net/evanyanglibo/article/details/122188952