【问题标题】:Stopping outer observable with switchmap without completing inner observables使用 switchmap 停止外部 observable 而不完成内部 observable
【发布时间】:2019-05-24 07:41:02
【问题描述】:

我已经搜索了一个类似的问题,但找不到匹配的问题,如果有重复,敬请见谅。

我有几个链式可观察对象。

Observable A 通过 switchmap 调用 Observable B。

现在 Observable B 实际上是一个行为主题,但我认为这与问题无关。

现在 observable B 永远不会完成。它不断地传递真假。

当 Observable B 接收到 true 值时,它会通过 switchmap 调用 Observable C。 Observable C 做事并通过 switchmap 调用其他 observables。以此类推。

我需要做的是当 observable B 收到 false 时,它​​什么也不做(目前是这样设置的)。当 observable B 收到 true 时,它​​会调用 observable C(当前有效)。现在它会传播到我的原始订阅,我很乐意使用我上次观察到的结果。

但是......它永远不会完成,因为 Observable B 永远不会完成。如何在不停止链发生后停止可观察 B 完成或取消订阅它?因此,当 Observable B 再次获得 .next(true) 时,它会再次触发链,而不是我想要的。

我尝试使用takeUntil,我传递了一个可观察对象,当接收到真值时触发。 takeUntil 的问题是一切都立即完成,我的订阅从未收到任何值(Observable C 并且永远不会触发)。

这是一些删除了逻辑的代码。

private initMap(): Observable<boolean> {
      return this.platformHelperService.getUserLocation().pipe(
        switchMap(_ => {
         return this.updateMapCenterLocation();

public updateMapCenterLocation(): Observable<boolean> {
    let mapCenterSetObserver: Observer<void>;
    const mapCenterSetObsersable = Observable.create(
      (observer: Observer<void>) => {
        mapCenterSetObserver = observer;
      }
    );

    // This is observable B
    return this.mapAssignedBehaviorSubject.pipe(
        switchMap(assigned => {
        if (assigned) {
          // Observable C below. Later my subscription does more after this completes
          return this.platformHelperService.getUserLocation()
          // If I run below my initial subscription finishes right away and C never runs.
          // If I don't run this, subscription B never completes.
          mapCenterSetObserver.next(undefined);
          mapCenterSetObserver.complete();
        }
   }),
   takeUntil(mapCenterSetObsersable)
   );
  }

【问题讨论】:

    标签: angular typescript rxjs


    【解决方案1】:

    在可观察对象 B 中让 true 通过一次可能会起作用。

    .... 
    ObservableA.pipe(
    switchMap(()=>observableB.pipe(filter(res=>res),take(1))
    switchMap(()=>ObservableC())
    )
    

    【讨论】:

    • 我不需要 take(1)。当 B 为真时,我需要它来取消订阅。感谢您的帮助,但我不确定我是否理解您描述的真正通行证的概念。
    • 过滤器只会让真正的布尔值通过,如果它是真的,它只会使用 take(1) 发出一次,并且 ObservableB 将完成
    猜你喜欢
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2018-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    相关资源
    最近更新 更多