rxjs - rxjs observable debounceTime 内部 next 被忽略
问题描述
似乎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
如果我将 a 添加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
解决方案
这类问题似乎有些问题,可以通过使用神奇地修复,delay(0)
或者setTimeout
通常意味着您期望 RxJS 一直异步运行,而实际上它通常同步运行,除非被迫这样做。
这正是你的情况。
当 debounce 推动它的值时,你在这条线上https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100。
在
subscribe
你调用的里面next
,它到达了https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L84里面设置和内部变量。_next
debounceTime
lastValue
hasValue
现在它开始在调用堆栈中向上移动,直到现在它才停止处理这一行https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100。此时它会继续并覆盖
lastValue
并hasValue
再次覆盖https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L101-L102。这将它们设置为null
和false
。然后之后
300ms
debounceTime
想要发出它的值,但是https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L99因为它已经被覆盖了hasValue
。null
顺便说一句,更优雅的方式是将observeOn
操作员与async
调度程序一起使用,这样应该会提高性能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)
});
见更新演示:https ://stackblitz.com/edit/typescript-tsek9s?file=index.ts
编辑:这种行为在 RxJS 6 中可能已经改变:https ://github.com/ReactiveX/rxjs/pull/3218