angular - RxJS: debounceTime retorna todos os valores
É possível executar uma sequência com atraso, se nenhum outro evento estiver chegando, e retornar todos os valores de uma vez?
Eu preciso de algum tipo de função debounceTime, mas que retorne todos os valores.
Resposta #1
Se eu entendi corretamente, você precisa de um operador que armazene eventos até que nenhum evento ocorra por um determinado período de tempo, e então repita todos os eventos armazenados. Eu tentaria isto:
Defina este novo operador no protótipo do Observable:
function bufferedDebounceTime(time) {
return Observable.create(subscriber => {
let buffer = [];
return this.do(x => buffer.push(x))
.debounceTime(time)
.flatMap(() => buffer)
.do(() => buffer = [])
.subscribe(
value => subscriber.next(value),
err => subscriber.error(err),
() => subscriber.complete()
);
});
}
Observable.prototype.bufferedDebounceTime = bufferedDebounceTime;
Então use-o como um operador:
yourSourceObservable.bufferedDebounceTime(1000).subscribe(...)
Resposta #2
EDITAR
bufferTime de fato age como um intervalo infinito, então não é recomendado. Como Jørgen Tvedt comentou, debounceTime + buffer é o que você está procurando.
No entanto, como este é um operador muito útil, eu criei o meu personalizado que torna tudo muito mais fácil, eu o chamei de bufferDebounce
Eu fiz isso como uma OperatorFunction em Typescript para forçar a inferência de tipos ao longo do pipeline:
type BufferDebounce = <T>(debounce: number) => OperatorFunction<T, T[]>;
const bufferDebounce: BufferDebounce = debounce => source =>
new Observable(observer =>
source.pipe(buffer(source.pipe(debounceTime(debounce)))).subscribe({
next(x) {
observer.next(x);
},
error(err) {
observer.error(err);
},
complete() {
observer.complete();
},
})
);
Você pode testar você mesmo neste exemplo funcional https://stackblitz.com/edit/rxjs6-buffer-debounce
RESPOSTA ANTERIOR
Com o RXJS 6+ você pode fazer isso muito facilmente.
Como ZahiC mencionou, a resposta está nos buffers, mas especificamente você pode fazer tudo isso com bufferTime Como usar bufferTime
Então, onde quer que seu source esteja (como observável), você pode:
// This will capture all responses, and return it in an Array every 2 secs
const example = source.pipe(bufferTime(2000));
