Angular定时GET请求未触发后端:每10秒请求失效问题求助
每10秒发起Angular GET请求更新数据的问题
问题背景
我的Angular服务中编写了如下GET请求方法:
public sendUpdate(idBombeamento: number): Observable<any> { const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('access_token')}` }); //console.log(headers.get('Authorization')); const requestOptions = { headers: headers }; return this.http.get<any>(`${this.url}/${idBombeamento}`, requestOptions); }
组件代码如下:
import { catchError, interval, map, Observable, switchMap, throwError } from 'rxjs'; export class BombeamentoComponent implements OnInit{ protected idBombeamento: number = 0; protected retornoChamado: any; constructor( private bombService: BombeamentoService, private routeA: ActivatedRoute, private _snackBar: MatSnackBar, private http: HttpClient){ this.routeA.params.subscribe(params => { this.idBombeamento = params['id']; }); } }
需求与问题
我需要每10秒发起一次GET请求,以更新组件数据。项目依赖如下:
"dependencies": { "@angular/animations": "^16.1.0", "@angular/cdk": "^16.2.0", "@angular/common": "^16.1.0", "@angular/compiler": "^16.1.0", "@angular/core": "^16.1.0", "@angular/forms": "^16.1.0", "@angular/material": "^16.2.0", "@angular/platform-browser": "^16.1.0", "@angular/platform-browser-dynamic": "^16.1.0", "@angular/router": "^16.1.0", "@auth0/angular-jwt": "^5.1.2", "rxjs": "~7.8.0", "tslib": "^2.3.0", "zone.js": "~0.13.0" }
我尝试了两种方式,但GET请求并未每10秒发送到后端,始终返回第一次请求的响应:
方式一:
ngOnInit():void{ setInterval(() => { this.bombService.sendUpdate(this.idBombeamento).subscribe({ next: (res)=>{ this.retornoChamado = res; this.openSnackBar1("Enviado com sucesso!","",false); console.log(this.retornoChamado); }, error:(e)=>console.log(e), }); }, 10000); }
方式二:
ngOnInit():void{ interval(10000).subscribe(res=>{ this.bombService.sendUpdate(this.idBombeamento).subscribe((res2)=>{ console.log("passou"); console.log(res2); }) }); }
解决方案
1. 禁用浏览器GET请求缓存
问题核心是浏览器默认会缓存GET请求的响应,导致后续请求直接读取本地缓存而非发送到后端。需要在请求头中添加缓存控制指令:
修改服务中的sendUpdate方法:
public sendUpdate(idBombeamento: number): Observable<any> { const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('access_token')}`, // 添加缓存禁用头,强制每次请求都发往后端 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' }); const requestOptions = { headers: headers }; return this.http.get<any>(`${this.url}/${idBombeamento}`, requestOptions); }
2. 优化RxJS订阅写法(避免嵌套订阅+内存泄漏)
使用switchMap替代嵌套订阅,同时在组件销毁时取消订阅,避免内存泄漏:
修改组件代码:
import { catchError, interval, switchMap, throwError, Subscription } from 'rxjs'; import { OnInit, OnDestroy } from '@angular/core'; export class BombeamentoComponent implements OnInit, OnDestroy{ protected idBombeamento: number = 0; protected retornoChamado: any; private refreshSubscription?: Subscription; constructor( private bombService: BombeamentoService, private routeA: ActivatedRoute, private _snackBar: MatSnackBar, private http: HttpClient){ this.routeA.params.subscribe(params => { this.idBombeamento = params['id']; }); } ngOnInit(): void { // 每10秒发起请求,用switchMap处理嵌套逻辑 this.refreshSubscription = interval(10000) .pipe( switchMap(() => this.bombService.sendUpdate(this.idBombeamento)), catchError(err => { console.error(err); return throwError(() => err); }) ) .subscribe({ next: (res) => { this.retornoChamado = res; this.openSnackBar1("Enviado com sucesso!","",false); console.log(this.retornoChamado); } }); } ngOnDestroy(): void { // 组件销毁时取消订阅,释放资源 if(this.refreshSubscription){ this.refreshSubscription.unsubscribe(); } } }
说明
- 缓存禁用头会强制浏览器跳过本地缓存,每次都向后端发送新请求;
switchMap可以避免嵌套订阅的回调问题,同时在组件销毁时,取消订阅会自动终止未完成的请求,减少无效网络开销。
内容的提问来源于stack exchange,提问作者Rodrigo Steinhorst
相关产品推荐
相关产品推荐

