【问题标题】:RxJs - Can I use a BehaviorSubject with takeUntil?RxJs - 我可以在 takeUntil 中使用 BehaviorSubject 吗?
【发布时间】:2018-07-28 07:53:47
【问题描述】:

我想通过使用 BehaviorSubject 的 takeUntil 取消订阅另一个 Observable。当我使用 takeUntil 订阅 Observable 时,它​​似乎立即取消订阅。此代码适用于主题,但我想要一个初始值集。

我正在使用 rxjs 5.5.6

//MyService1
class Observable1 {
  status1: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  displayStatus1(val: boolean) {
    this.status1.next(val)
  }
}

//MyService2
class Observable2 {
  status2: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  displayStatus2(val: boolean) {
    this.status2.next(val)
  }
}

//MyComponent
status: boolean;

constructor(private myService1: MyService1, private myService2: MyService2) {
   this.subscribeToObservable1();
   this.subscribeToObservable2();
}

subscribeToObservable1() {
  this.myService1.status1.subscribe((val: boolean) => {
    console.log('val: ', val);
  }
}

subscribeToObservable2() {
  this.myService2.status2
    .takeUntil(this.myService1.status1)
    .subscribe((val: boolean) => {
      this.status = val;
    }
}

【问题讨论】:

    标签: javascript rxjs5 behaviorsubject


    【解决方案1】:

    你在 takeWhile 之后:(因为 takeUntil 不带谓词)。

    var bs = new Rx.BehaviorSubject<boolean>(false); //create beahviour subject
    const source = Rx.Observable.interval(1000);     //create observable
    // take from obs while , behaviour subject not emitting true
    const example = source.takeWhile ((a)=>bs.value!=true); 
    const subscribe = example.subscribe(val => console.log(val));
    
    setTimeout(()=>bs.next(true),3000); //make the BehaviorSubject emit true and stop.
    

    http://jsbin.com/yaditucija/1/edit?js,console

    【讨论】:

      【解决方案2】:

      一个 BehaviorSubject 会有一个初始值。 因此,一旦您的 takeUntil 在内部订阅它,它将释放其初始值。 见(这里)[http://reactivex.io/documentation/subject.html]

      When an observer subscribes to a BehaviorSubject, it begins by emitting the item most recently emitted by the source Observable (or a seed/default value if none has yet been emitted) and then continues to emit any other items emitted later by the source Observable(s).

      请改用PublishSubject

      【讨论】:

      • 在javascript中只需使用简单的Subject
      • 使用skip(1)可以跳过第一个初始值
      【解决方案3】:

      当然可以,只需使用skip() 跳过第一个初始值:

      this.status2$
          .pipe(
              takeUntil(
                 this.status1$.pipe(skip(1))
              ),
          )
          .subscribe((val: boolean) => {
               // I execute until status1$ emits
          }
      

      顺便说一句:从 RxJS >= 5.5 开始,您可能会使用 pipe,就像我的示例一样。你也可以在末尾用$ 命名你的可观察对象,这样它就变成了“status1stream”

      【讨论】:

      • 感谢这对我帮助很大!
      【解决方案4】:

      您也可以使用过滤器。

      const source = new Subject();
      const destory$ = new BehaviorSubject<boolean>(false);
      source
        .pipe(takeUntil(destory$.pipe(filter((v: boolean) => v))))
        .subscribe(resp => {
          console.log("resp", resp);
        });
      
      source.next("hello");
      
      source.next("hello2");
      destory$.next(true);
      destory$.complete();
      source.next("hello 3 ");
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-26
        • 1970-01-01
        • 2019-11-15
        • 1970-01-01
        • 2020-09-27
        • 2017-05-04
        • 2019-07-22
        • 1970-01-01
        相关资源
        最近更新 更多