在 angular 9 中每隔 x 分钟调用一次 http 请求
Make http request call every x minute in angular 9
我正在尝试创建一个动态组件,它将使用 api url 和 intervalPeriod 说 'x' 分钟作为输入,并每隔 x 分钟获取作为输入传递的数据。
这是我尝试遵循所有 Whosebug 答案的 stackblitz..
我需要在 0 秒时第一次显示数据,之后它必须每隔 x 秒或每分钟获取一次数据。这看起来正确还是我在这里缺少什么?
https://stackblitz.com/edit/angular-wzvwmy?file=src%2Fapp%2Fdata-emitter%2Fdata-emitter.component.ts
import { Component, Input, OnInit, Output } from "@angular/core";
import { interval } from "rxjs";
import { flatMap, map } from "rxjs/operators";
import { Http } from "@angular/http";
@Component({
selector: "app-data-emitter",
templateUrl: "./data-emitter.component.html",
styleUrls: ["./data-emitter.component.css"]
})
export class DataEmitterComponent implements OnInit {
@Output() data: any;
@Input() apiUrl: any;
@Input() intervalPeriod: number;
minutes: number;
constructor(private http: Http) {}
ngOnInit() {
this.minutes = this.intervalPeriod * 60 * 1000;
}
subscribes$ = interval(this.minutes)
.pipe(flatMap(() => this.getData()))
//this.getData()
.subscribe(data => {
this.data = data;
console.log(this.data);
});
getData() {
return this.http
.get(this.apiUrl)
.pipe(map((response: any) => response.json()));
}
}
有几件事我会改变:
- 如果您使用 Angular >= 4.3.1
,请使用新的 HttpClient
- 您应该在 ngOnDestroy 中取消订阅以免泄露订阅。
- 将间隔更改为初始时间为 0 的定时器,以便立即执行第一个调用。
- 移动订阅到 ngOnInit,否则订阅会在设置 intervalPeriod 之前创建,并导致间隔的默认周期为 0。
- catchError 如果你希望你的间隔在一个调用失败时保持活跃。
- 将 flatMap 更改为 switchMap 以最多有一个 http 调用,没有重叠调用。如果第一次调用没有完成,则在进行第二次调用时将使用 switchMap 取消。这不太可能间隔 1 分钟,因此没有必要。
import { Component, Input, OnDestroy, OnInit, Output } from "@angular/core";
import { HttpClient } from '@angular/common/http';
import { of, Subscription, timer } from "rxjs";
import { catchError, filter, switchMap } from "rxjs/operators";
@Component({
selector: "app-data-emitter",
templateUrl: "./data-emitter.component.html",
styleUrls: ["./data-emitter.component.css"]
})
export class DataEmitterComponent implements OnInit, OnDestroy {
@Output() data: any;
@Input() apiUrl: any;
@Input() intervalPeriod: number;
minutes: number;
subscription: Subscription;
constructor(private http: HttpClient) {}
ngOnInit() {
this.minutes = this.intervalPeriod * 60 * 1000;
this.subscription = timer(0, this.minutes)
.pipe(
switchMap(() => {
return this.getData()
.pipe(catchError(err => {
// Handle errors
console.error(err);
return of(undefined);
}));
}),
filter(data => data !== undefined)
)
.subscribe(data => {
this.data = data;
console.log(this.data);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
getData() {
return this.http
.get(this.apiUrl);
}
}
我正在尝试创建一个动态组件,它将使用 api url 和 intervalPeriod 说 'x' 分钟作为输入,并每隔 x 分钟获取作为输入传递的数据。
这是我尝试遵循所有 Whosebug 答案的 stackblitz..
我需要在 0 秒时第一次显示数据,之后它必须每隔 x 秒或每分钟获取一次数据。这看起来正确还是我在这里缺少什么?
https://stackblitz.com/edit/angular-wzvwmy?file=src%2Fapp%2Fdata-emitter%2Fdata-emitter.component.ts
import { Component, Input, OnInit, Output } from "@angular/core";
import { interval } from "rxjs";
import { flatMap, map } from "rxjs/operators";
import { Http } from "@angular/http";
@Component({
selector: "app-data-emitter",
templateUrl: "./data-emitter.component.html",
styleUrls: ["./data-emitter.component.css"]
})
export class DataEmitterComponent implements OnInit {
@Output() data: any;
@Input() apiUrl: any;
@Input() intervalPeriod: number;
minutes: number;
constructor(private http: Http) {}
ngOnInit() {
this.minutes = this.intervalPeriod * 60 * 1000;
}
subscribes$ = interval(this.minutes)
.pipe(flatMap(() => this.getData()))
//this.getData()
.subscribe(data => {
this.data = data;
console.log(this.data);
});
getData() {
return this.http
.get(this.apiUrl)
.pipe(map((response: any) => response.json()));
}
}
有几件事我会改变:
- 如果您使用 Angular >= 4.3.1 ,请使用新的 HttpClient
- 您应该在 ngOnDestroy 中取消订阅以免泄露订阅。
- 将间隔更改为初始时间为 0 的定时器,以便立即执行第一个调用。
- 移动订阅到 ngOnInit,否则订阅会在设置 intervalPeriod 之前创建,并导致间隔的默认周期为 0。
- catchError 如果你希望你的间隔在一个调用失败时保持活跃。
- 将 flatMap 更改为 switchMap 以最多有一个 http 调用,没有重叠调用。如果第一次调用没有完成,则在进行第二次调用时将使用 switchMap 取消。这不太可能间隔 1 分钟,因此没有必要。
import { Component, Input, OnDestroy, OnInit, Output } from "@angular/core";
import { HttpClient } from '@angular/common/http';
import { of, Subscription, timer } from "rxjs";
import { catchError, filter, switchMap } from "rxjs/operators";
@Component({
selector: "app-data-emitter",
templateUrl: "./data-emitter.component.html",
styleUrls: ["./data-emitter.component.css"]
})
export class DataEmitterComponent implements OnInit, OnDestroy {
@Output() data: any;
@Input() apiUrl: any;
@Input() intervalPeriod: number;
minutes: number;
subscription: Subscription;
constructor(private http: HttpClient) {}
ngOnInit() {
this.minutes = this.intervalPeriod * 60 * 1000;
this.subscription = timer(0, this.minutes)
.pipe(
switchMap(() => {
return this.getData()
.pipe(catchError(err => {
// Handle errors
console.error(err);
return of(undefined);
}));
}),
filter(data => data !== undefined)
)
.subscribe(data => {
this.data = data;
console.log(this.data);
});
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
getData() {
return this.http
.get(this.apiUrl);
}
}