我在Angular 5中编写单页应用程序,它需要定期检查API是否仍然与加载SPA时的版本相同,以通知用户desync并允许她刷新(第一次调用必须尽快执行尽可能)。
我没有使用rxjs的经验,我知道如果我不小心,我可能会以未订阅的observable和/或更多的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();
});
}
}
console.log("Quick version check");
this.keepAliveService.performCheckVersion();
console.log("Set check version setInterval");
setInterval(() => {
this.keepAliveService.performCheckVersion();
}, this.checkVersionInterval);
这样做的工作,但我觉得这么简单的工作似乎相当复杂。是否有“Observableish”方式获得相同的功能?
我尝试过以下方法:
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",
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;
});
}