似乎debounceTime
忽略了内部调用它的主题next
方法:
var subject: Subject<number> = new Subject<number>();
subject.pipe(
tap((a) => console.log("tab:" + a)),
debounceTime(300),
).subscribe((a) => {
console.log(a);
subject.next(100)
});
subject.next(19);
subject.next(20);
上面的代码应该创建一个无限循环 - 但它不会:
tab:19
tab:20
20
tab:100
如果我向管道添加delay(1)
,它按预期工作:
subject.pipe(
tap((a) => console.log("tab:" + a)),
debounceTime(300),
delay(1)
).subscribe((a) => {
console.log(a);
subject.next(100)
});
我错过了什么吗?
修改:添加了一个示例:https://typescript-fbt2mn.stackblitz.io
答案 0 :(得分:3)
这种类似的问题似乎已被打破并且可以通过使用delay(0)
或setTimeout
进行神奇修复,这通常意味着您期望RxJS始终以异步方式运行事实上它通常同步工作,除非被迫做其他事情。
这正是你的情况。
当去抖动推动其价值时,你就在https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100这一行。
在subscribe
内,您致电next
_next
debounceTime
lastValue
hasValue
lastValue
和hasValue
内部变量。
现在它开始在调用堆栈中向上运行,现在它才停止处理此行https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L84。此时,它会继续并再次覆盖null
和false
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100。这会将它们设置为300ms
和debounceTime
。
然后在hasValue
null
想要发出其值但observeOn
为async
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L101-L102之后,因为它已被覆盖。
顺便说一句,更优雅的方法是使用delay(1)
运算符和import { async } from 'rxjs/scheduler/async';
var obs = Observable.of(1, 2, 3);
var subject: Subject<number> = new Subject<number>();
subject.pipe(
tap((a) => console.log("tab:" + a)),
debounceTime(300),
observeOn(async),
).subscribe((a) => {
console.log(a);
subject.next(a+1)
});
调度程序,它应该比{{1}}更具性能效率。
{{1}}
见最新演示:https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L99
编辑:此行为可能已在RxJS 6中更改:https://stackblitz.com/edit/typescript-tsek9s?file=index.ts