我想使用RxJs实现以下目标:
由于有关于SO的其他几个问题,例如this one,使用buffer
和debounceTime
的组合很容易实现1和2,就像这样:
const subject$ = new Subject<number>();
// Create the debounce
const notifier$ = subject$.pipe(
debounceTime(250)
);
// Subscribe to the subject using buffer and debounce
subject$
.pipe(
buffer(notifier$)
)
.subscribe(value => console.log(value));
// Add a number to the subject every 200ms untill it reaches 10
interval(200)
.pipe(
takeWhile(value => value <= 10),
)
.subscribe(value => subject$.next(value));
只要在最后一条消息的200ms之内发出消息,这些消息就会被缓冲。如果花费超过200毫秒,则会启动一个新的缓冲区。但是,如果消息持续不到200毫秒,则消息可能会永远被缓冲。这就是为什么我要对缓冲区大小添加硬限制。
我在StackBlitz创建了一个示例来演示缓冲区的去抖动。但是我不知道如何限制缓冲区,以便它也可以在达到10个项目时发出。
答案 0 :(得分:1)
我们可以创建另一个通知程序来限制项数(例如,使用elementAt
),使用首先发出的通知程序(使用race
)并递归应用(使用expand
):
const notifierDebouncing$ = subject$.pipe(
debounceTime(PERIOD),
take(1)
);
const notifierLimiting$ = subject$.pipe(
elementAt(AMOUNT - 1)
);
const notifier$ = interval(0).pipe(
take(1),
expand(_ => race(notifierLimiting$, notifierDebouncing$))
);
subject$
.pipe(buffer(notifier$))
.subscribe(value => console.log(value));
你怎么看?
以下是一个示例,该示例基于您的演示应用程序:https://stackblitz.com/edit/rxjs-buffer-debounce-cf4qjy (打开控制台,然后将光标移动2000ms,然后停止500ms)
答案 1 :(得分:0)
您不能只过滤它的第十个项目吗?也许我误解了你的问题。
interval(this.interval)
.pipe(
filter(value => value % 10 === 0),
takeWhile(value => value <= this.amount),
)
.subscribe(value => this.subject$.next(value));
}