Pesquisa de site

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));

Artigos relacionados