RxJs Interval与takeUntil一起发布最后一个值

时间:2018-08-09 12:35:19

标签: angular6 rxjs6 rxjs-pipeable-operators

我有一些代码可以轮询直到任务完成

见下文

this.simulationStatus =
  interval(2000).pipe(
    switchMap(
      () => from(this.simulationService.getSimulationStatus(this.route.snapshot.paramMap.get('jobId')))),
    takeUntil(this.stopPoll),
    tap(simulation => {
      if (simulation && simulation.complete) {
        if (this.stopCount == 1) {
          // Get once after complete
          this.stopPoll.next(true);
        }
        this.stopCount++;
      }
    })
  );

我尝试使用takeUntil和takeWhle,但问题是,一旦任务完成,最后的值将永远不会发布。

要解决这个问题,我必须在stopPoll主题中包含tap方法,并增加stopCount以获得最后一个值。

因此上述方法有效,但感觉有点混乱,我确定必须有更好的方法来实现这一目标?

我本来希望takeUntil发布最后一个值,或者有一个覆盖值来告知它,例如takeUntil(observable,{publishLast:true})

BTW更新,可观察对象已由Angular 6模板订阅 预先感谢

3 个答案:

答案 0 :(得分:1)

如果您想完成可观察对象,也可以创建主题并使用next()发出。

this.stopPoll: Subject<any> = new Subject<any>();

如果要完成订阅。您可以调用this.stopPoll.next(true);

您可以在subscribe()中访问数据

this.simulationStatus.subscribe(success=>{}, failure=>{}, complete=>{});

答案 1 :(得分:1)

您可以做的一件事是使用自定义的类似takeWhile的运算符:

const completeWith = <T>(predicate: (arg: T) => boolean) => (
  source: Observable<T>,
) =>
  new Observable<T>(observer =>
    source.subscribe(
      value => {
        observer.next(value);
        if (predicate(value)) {
          observer.complete();
        }
      },
      error => observer.error(error),
      () => observer.complete(),
    ),
  );

将其视为takeWhite的变体似乎不是一个好主意,因为它不仅是采用 且条件成立,而且还会发出额外的值。

也许更优雅的解决方案是使可观察的模拟状态发出两种值:下一个通知和完成通知,类似于实现/取消实现操作员的工作方式。

答案 2 :(得分:0)

这同时在 rxjs 中实现为 takeWhile(condition, ?inclusive)

timer(0, 10).pipe(
    takeWhile((x) => x < 3, true)
)

发出 0, 1, 2, 3