一旦关闭复选框,我试图使用takeUntil停止流。我在Angular中,所以现在我只是在类属性上串联一个字符串,而不用担心将可观察对象的结果串联在一起。

this.checked$是一个BehaviorSubject,它开始于false,并且在取消/激活我的复选框时得到next。该部分至少在一定程度上可以正常工作,因为下面将开始显示点。但是,添加(注释如下)takeUntil(this.checked$)根本不会显示任何点。

const source$ = interval(250).pipe(mapTo("."));
this.checked$
.pipe(
  filter(c => {
    return c === true;
  }),
  switchMap(() => {
    console.log("switchMap");
    // return source$.pipe(takeUntil(this.checked$));
    return source$;
  })
)
.subscribe(data => {
  console.log("in subscribe", data, this.dots);
  this.dots += data;
});


我在这里如何使用BehaviorSubjecttakeUntil有什么不正确的地方?

Here is a full example is on StackBlitz

最佳答案

请注意,takeUntil仅在发出第一个checked$之前发出值,here是很好的示例。因为checked$BehaviorSubject,所以当您预订它时会立即发出当前值,结果takeUntil停止。

一个解决方案可能是在source$和switchMap内部的一个可观察到的空白之间切换,例如:

const source$ = interval(250).pipe(mapTo("."));
this.checked$
  .pipe(
    switchMap(c => {
      console.log("switchMap");
      return c ? source$ : EMPTY;
    })
  )
  .subscribe(data => {
    console.log("in subscribe", data, this.dots);
    this.dots += data;
  });


StackBlitz example



您也可以跳过checked$主题的第一个值来修复原始解决方案,但是我建议您使用先前的解决方案,因为它更简单。

const source$ = interval(250).pipe(mapTo("."));
this.checked$
  .pipe(
    filter(c => {
      return c === true;
    }),
    switchMap(() => {
      console.log("switchMap");
   // return source$.pipe(takeUntil(this.checked$));
      return source$.pipe(takeUntil(this.checked$.pipe(skip(1))));
    })
  )
  .subscribe(data => {
    console.log("in subscribe", data, this.dots);
    this.dots += data;
  });


StackBlitz example



另一种解决方案是使用Subject代替BehaviorSubject。区别在于Subject不保存当前值,订阅时不发出任何值。仅在调用next()时发出。如果在原始解决方案中将BehaviorSubject替换为Subject,它将按预期工作。

StackBlitz example

10-04 16:02