Как периодически опрашивать информацию в Angular 5, используя Observables, а также получать немедленную выборку, используя RxJs 5.x? - PullRequest
1 голос
/ 12 марта 2019

Я кодирую одностраничное приложение на Angular 5, и ему требуется периодически проверять, имеет ли API все еще ту же версию, что и при загрузке SPA, чтобы информировать пользователя о рассинхронизации и позволить ему обновить (первый вызов должен быть выполняется как можно скорее).

У меня мало опыта работы с rxjs, и я знаю, что если я не буду осторожен, я могу закончить с отписанными наблюдаемыми и / или большим количеством HTTP-вызовов, чем требуется.

Мой текущий код выглядит так:

Услуга

import { Injectable } from "@angular/core";
import { IValidationResult } from "../models/validation-result";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs/Observable";
import { HttpClient } from "@angular/common/http";

@Injectable()
export class KeepAliveService {

  checkVersion$: Observable<IValidationResult<string>>;
  checkVersionSubscription: Subscription;

  constructor(
    private readonly httpClient: HttpClient) {
  }

  isUpToDate: boolean;
  isLive = true;
  liveVersion: string;

  performCheckVersion(): void {

    const localVersion = localStorage.getItem("MyAppLocalVersion");

    this.checkVersion$ = this.httpClient.get<IValidationResult<string>>("GetApiVersion");

    this.checkVersionSubscription = this.checkVersion$.subscribe(
      (result: IValidationResult<string>) => {
        this.liveVersion = result.payload;
        this.isUpToDate = localVersion === this.liveVersion;
        this.isLive = true;

        this.checkVersionSubscription.unsubscribe();
    });
  }
}

Обновление кода (app.module.ts)

console.log("Quick version check");
this.keepAliveService.performCheckVersion();

console.log("Set check version setInterval");
setInterval(() => {
  this.keepAliveService.performCheckVersion();
}, this.checkVersionInterval);

Это делает работу, но я чувствую, что это довольно сложно для такой простой работы. Есть ли «наблюдаемый» способ получения такой же функциональности?

<Ч />

Я пробовал следующее:

Служба

import { Injectable } from "@angular/core";
import { IValidationResult } from "../models/validation-result";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs/Observable";
import { HttpClient } from "@angular/common/http";
import { interval } from "rxjs/observable/interval";
import { switchMap } from "rxjs/operator/switchMap";

  startCheckingVersion() {

    const httpObservable = interval(this.checkVersionInterval)
      .switchMap(_ => this.httpClient.get<IValidationResult<string>>("GetApiVersion"));  

      this.checkVersionSubscription = httpObservable.subscribe(
        (result: IValidationResult<string>) => {
          const localVersion = localStorage.getItem("MyAppLocalVersion");
          this.liveVersion = result.payload;
          this.isUpToDate = localVersion === this.liveVersion;
          this.isLive = true;
        });
  }

Однако существует проблема, связанная с тем, как я использую timer и switchMap, поскольку я получил следующую ошибку:

timer_1.timer (...). SwitchMap не является функцией; Зона:; Задача: Promise.then; Значение: TypeError: timer_1.timer (...). SwitchMap не является функция

Моя версия package.json rxjs:

"rxjs": "^5.5.6",

1 Ответ

1 голос
/ 12 марта 2019

jcuypers правильно показал мне, как заставить это работать, и исходный код значительно уменьшен:

услуга

import { Injectable } from "@angular/core";
import { IValidationResult } from "../models/validation-result";
import { Subscription } from "rxjs/Subscription";
import { Observable } from "rxjs/Observable";
import { HttpClient } from "@angular/common/http";

// had to pay attention to the imports
import { switchMap } from "rxjs/operators";
import { timer } from "rxjs/observable/timer";

@Injectable()
export class KeepAliveService {

  readonly checkVersionInterval = 30000;

  constructor(
    private readonly httpClient: HttpClient) {
  }

  isUpToDate: boolean;
  isLive = true;
  liveVersion: string;

  startCheckingVersion() {

    // use pipe with switchMap to perform the http call at time 0 + every some interval
    const httpObservable = timer(0, this.checkVersionInterval)
      .pipe(switchMap(_ => this.httpClient.get<IValidationResult<string>>("GetApiVersion")));

      this.checkVersionSubscription = httpObservable.subscribe(
        (result: IValidationResult<string>) => {
          const localVersion = localStorage.getItem("MyAppLocalVersion");
          this.liveVersion = result.payload;
          this.isUpToDate = localVersion === this.liveVersion;
          this.isLive = true;
        });
  }
...