RXJS:节流时间加上最后一个值

时间:2018-08-27 11:15:06

标签: rxjs

我有一个场景,可以在短时间内将许多事件发送到流中。我想要一个混合了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;
        });
    }
}

2 个答案:

答案 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 }));
}