rxjs observable debounceTime inner next 被忽略
rxjs observable debounceTime inner next ignored
似乎 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)
});
我是不是漏了什么?
这类问题似乎被破坏了,但可以使用 delay(0)
或 setTimeout
神奇地修复,这通常意味着您期望 RxJS 在运行时始终异步运行事实上,它通常同步工作,除非被迫以其他方式进行。
这正是你的情况。
当 debounce 推动它的值时,你在这条线上 https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100。
在 subscribe
内调用 next
到达 _next
在 debounceTime
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L84 内设置 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
想要发出它的值但是 hasValue
是 null
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L99 因为它已经被覆盖了。
顺便说一句,更优雅的方法是将 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
似乎 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)
});
我是不是漏了什么?
这类问题似乎被破坏了,但可以使用 delay(0)
或 setTimeout
神奇地修复,这通常意味着您期望 RxJS 在运行时始终异步运行事实上,它通常同步工作,除非被迫以其他方式进行。
这正是你的情况。
当 debounce 推动它的值时,你在这条线上 https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L100。
在
subscribe
内调用next
到达_next
在debounceTime
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L84 内设置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
想要发出它的值但是hasValue
是null
https://github.com/ReactiveX/rxjs/blob/5.5.10/src/operators/debounceTime.ts#L99 因为它已经被覆盖了。
顺便说一句,更优雅的方法是将 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