[英]Rxjs: Observable with takeUntil(timer) keeps emitting after the timer has ticked
[英]RxJS - An observable 'A' doesn't stop emitting with a takeUntil that is piped from the same observable 'A'
我有一个可观察的,在单击开始按钮后每秒向控制台打印一个数字。 单击开始按钮 5 秒后,可观察对象应停止打印。
单击开始按钮后每秒开始条件
点击开始按钮五秒后结束条件
不起作用的代码
const startClick$ = fromEvent(document.getElementById('start'), 'click');
const stop$ = startClick$.pipe(switchMapTo(interval(5000)));
const printInterval$ = interval(1000).pipe(takeUntil(stop$));
const startPrint$ = startClick$.pipe(switchMapTo(printInterval$));
startPrint$.subscribe(
value => {
console.log('new value is:', value);
},
() => {
console.log('there was some error!');
},
() => {
console.log('i have completed');
}
);
stop$.subscribe(() => {
console.log('i should stop right now!!');
});
单击开始按钮后五秒钟后,startPrint$ Observable 不会停止发射。
有效的代码
const endClick$ = fromEvent(document.getElementById('end'), 'click');
const stopWithEndClick$ = endClick$.pipe(switchMapTo(interval(5000)));
const printInterval1$ = interval(1000).pipe(takeUntil(stopWithEndClick$));
const startPrint1$ = startClick$.pipe(switchMapTo(printInterval1$));
startPrint1$.subscribe(
value => {
console.log('1: new value is:', value);
},
() => {
console.log('1: there was some error!');
},
() => {
console.log('1: i have completed');
}
);
stopWithEndClick$.subscribe(() => {
console.log('1: i should stop right now!!');
});
在这里,我有另一个按钮end
,我在单击 end 按钮后 5 秒内执行。 在这种情况下,observable 会按预期停止发射。
我怎样才能使第一个案例工作,我在这里犯了任何错误吗? 整个工作代码可以在https://stackblitz.com/edit/take-until-issue?file=index.ts 找到
发生这种情况是因为 RxJS 运算符中的订阅顺序。 当您第一次单击“开始”按钮时,第一个收到通知的是stop$
,但没有人在收听stop$
,因此通知不会触发任何内容。 你看到"'i should stop right now!!'
只是因为你最后自己订阅了。
因此,最简单的解决方案是将stop$
链创建为一个 Observable,它只会在您订阅后开始发射,例如timer(5000)
,它只发射一次然后完成。
const stop$ = timer(5000);
您更新的演示: https://stackblitz.com/edit/take-until-issue-or4okm?file=index.ts
请注意,您可能会得到不同数量的结果,因为 RxJS (通常是 JavaScript)不能保证5000ms
正好是5000ms
。 这同样适用于1000ms
,因此有时事件可能会以不同的顺序触发。 如果您只想要 5 个结果,则更好地使用例如take(5)
。 此外,对于日志记录,最好使用例如tap(v => console.log(v))
这样您就不会再次订阅。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.