Angular. HTTP long polling

Из javascript.ru long-polling – способ взаимодействия с сервером.

  1. Запрос отправляется на сервер.
  2. Сервер не закрывает соединение, пока у него не возникнет сообщение для отсылки.
  3. Когда появляется сообщение – сервер отвечает на запрос, посылая его.
  4. Браузер немедленно делает новый запрос.

Для данного метода ситуация, когда браузер отправил запрос и удерживает соединение с сервером, ожидании ответа, является стандартной. Соединение прерывается только доставкой сообщений.

Функция имитации ответа от backend`a. Ответ возвращается через случайное время от 1 до 4 секунд.

function random(min, max) {
  const rand = min + Math.random() * (max + 1 - min);
  return Math.floor(rand);
}

const fakeHttpRequest = defer(() =>
  of(`Response ${Date.now()}`).pipe(delay(random(1000, 4000)))
);

// событие завершения long-polling
const stop$ = fromEvent(document.querySelector("button"), "click");

Реализция на RxJS:

  • Рекурсия через subject.next()
  • repeat

subject next

import { of, fromEvent, defer, Subject } from 'rxjs'; 
import { map, delay, repeat, takeUntil, concatMap, tap, startWith } from 'rxjs/operators';

const subject = new Subject();
subject.pipe(
    startWith(null),
    concatMap(() => httpRequest),
    tap(() => subject.next()),
    takeUntil(stop$)
).subscribe(x => console.log(x));

repeat

Подход с repeat мне кажется более понятным.

import { of, fromEvent, defer } from 'rxjs'; 
import { map, delay, repeat, takeUntil,  } from 'rxjs/operators';

httpRequest.pipe(
  repeat(),
  takeUntil(stop$)
).subscribe(x => console.log(x));

Stackblitz


Похожие записи

Angular Let Directive

*ngIf не отображает содержимое в falsy случаях (0, null, undefined) на async pipe, в пакете @rx-angular/template предлагается решение