我有一个场景,可以在短时间内将许多事件发送到流中。我想要一个混合了debounceTime和油门时间的运算符。
以下演示可以用来说明我想拥有的https://stackblitz.com/edit/rxjs6-demo-jxbght?file=index.ts。 我希望订户获得第一个发出的事件,然后等待x ms。如果在等待时间内发出了更多事件,则最后一个事件应在等待时间内发送给订户。就像去抖一样,应该在每个新发出的事件上重置等待时间。
如果在1秒钟内单击按钮3次,则应打印1和3。如果在1秒钟内仅单击1次,则应仅打印4。如果再单击3次,则应打印5和7。
这对于debounceTime不起作用,因为它不会给我第一个事件,对于节流时间也不起作用,因为在等待时间结束后,这不会给我最后一个发出的值。
关于如何实施此建议?
更新
我在Martins的帮助下创建了一个自定义运算符。不知道它是否可以100%正确地工作,或者是否有更好的方法来执行它,但是它似乎可以满足我的要求。
import { Observable, empty } from 'rxjs';
import { exhaustMap, timeoutWith, debounceTime, take, startWith } from 'rxjs/operators';
export function takeFirstThenDebounceTime(waitTime) {
return function takeFirstThenDebounceTimeImplementation(source) {
return Observable.create(subscriber => {
const subscription = source.
pipe(
exhaustMap(val => source.pipe(
timeoutWith(waitTime, empty()),
debounceTime(waitTime),
take(1),
startWith(val)
)),
)
.subscribe(value => {
subscriber.next(value);
},
err => subscriber.error(err),
() => subscriber.complete());
return subscription;
});
}
}
答案 0 :(得分:5)
在RxJS 6中,throttleTime
运算符还有一些其他选项,这些选项目前尚未记录,您可以在其中使它们在持续时间的开始和结束时发出。所以也许这可以为您提供帮助。
https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttleTime.ts#L55
https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/throttle.ts#L12
但是,由于您想重置每次发射的超时,因此会更加复杂。这应该是带有随机发射的简化示例,但我想知道是否有更简单的方法可以做到这一点:
const shared = source.pipe(shareReplay(1))
shared
.pipe(
exhaustMap(val => shared.pipe(
timeout(1000),
catchError(() => empty()),
debounceTime(1000),
take(1),
startWith(val),
))
)
.subscribe(v => console.log(v))
此演示在175ms间隔后会反跳。我希望这对您有意义。
演示:https://stackblitz.com/edit/rxjs6-demo-ztppwy?file=index.ts
答案 1 :(得分:0)
该运算符应为您提供第一个值,节流流和最后一个值:
export function throunceTime<T>(duration: number): MonoTypeOperatorFunction<T> {
return (source: Observable<T>) =>
merge(source.pipe(throttleTime(duration)), source.pipe(debounceTime(duration)))
.pipe(throttleTime(0, undefined, { leading: true, trailing: false }));
}