我有一个 Angular 服务,当我选择一个新项目时,我在服务中设置该项目 ID,并使用它进行多个子调用来获取该项目的子部分。代码看起来像这样
set item(myItem: Item) {
this._item = item;
this.selectedItemUpdate.next(this._item);
this.getItemSubPartOne(this._item.id);
this.getItemSubPartTwo(this._item.id);
this.getItemSubPartThree(this._item.id);
}
......
getItemSubPartOne(id: string) {
let url = ...
this.httpClient.get(url).subscribe(
(res:Result) => {
this.itemSubPartOneUpdate.next(res);
}
}
考虑到这种模式,如果其中一个子部分尚未返回,但用户选择了不同的项目,我需要做什么来重建它。我需要取消所有以前的 http 请求。
要使用 RxJS 在 Angular 中取消先前的 HTTP 请求,您可以使用 switchMap 运算符,当发出新值时,它将取消任何正在进行的请求。这是一个基本食谱:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Subject, Observable } from 'rxjs';
import { switchMap, takeUntil } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class DataService {
private cancelPendingRequests = new Subject<void>();
constructor(private http: HttpClient) {}
// Call this method to cancel all pending HTTP requests
public cancelPendingOperations() {
this.cancelPendingRequests.next();
}
public getData(url: string): Observable<any> {
// Before making a new request, cancel any previous ones
this.cancelPendingOperations();
return this.cancelPendingRequests.pipe(
switchMap(() => this.http.get(url)),
takeUntil(this.cancelPendingRequests)
);
}
}
在您的组件中,每当需要发出新请求时,您都可以调用
getData()
,它将自动取消之前尚未完成的任何请求。当您的组件被销毁时,请记住调用 cancelPendingOperations()
以清除任何待处理的请求。
这是一个简化的示例,您可能需要对其进行调整以适应您的应用程序的具体情况。对于更复杂的场景,您可能需要考虑使用高阶映射运算符,例如
exhaustMap
或 concatMap
,具体取决于您想要实现的行为。