【问题标题】:How to periodically poll information in Angular 5 using Observables and also have immediate fetch using RxJs 5.x?如何使用 Observables 定期轮询 Angular 5 中的信息并使用 RxJs 5.x 立即获取?
【发布时间】:2019-03-12 08:46:27
【问题描述】:

我正在使用 Angular 5 编写单页应用程序,它需要定期检查 API 是否仍具有与加载 SPA 时相同的版本,以通知用户有关不同步并允许她刷新(第一次调用必须是尽快执行)。

我几乎没有使用 rxjs 的经验,而且我知道如果我不小心,我可能会以未订阅的 observables 和/或比所需更多的 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;
        });
  }

但是,当我收到以下错误时,存在与我如何使用 timerswitchMap 相关的问题:

timer_1.timer(...).switchMap 不是函数;区域:;任务: 承诺.then ;值:TypeError:timer_1.timer(...).switchMap 不是 功能

我的 package.json rxjs 版本:

"rxjs": "^5.5.6",

【问题讨论】:

  • @jcuypers - 我获得了httpObservable,它的类型是Observable&lt;IValidationResult&lt;string&gt;&gt;,我在下面两行订阅了它:this.checkVersionSubscription = httpObservable.subscribe( ...
  • 是的,我明白了。但我不明白 httpclient 调用本身是如何被订阅的(第一次订阅时你只激活间隔)......这应该由 switchmap 自动完成(实际的 http 调用订阅)
  • @jcuypers - 虽然引用的问题是针对 rxjs 6(我使用的是 5.5),但导入和管道对我来说工作正常。谢谢。
  • 抱歉,错过了。但还不错

标签: angular angular5 observable rxjs5 polling


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2018-11-24
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2023-03-03
    • 2020-05-05
    • 1970-01-01
    相关资源
    最近更新 更多