一旦关闭复选框,我试图使用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;
});
我在这里如何使用
BehaviorSubject
和takeUntil
有什么不正确的地方?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