在Angular组件上使用ngOnDestroy()方法,如果http请求在离开页面时仍悬而未决,我们将取消它们。在某些页面上,我们使用自定义的通用缓存助手来防止重新加载已经加载的数据。
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { AsyncSubject } from "rxjs";
@Injectable()
export class HttpCacheHelper {
public cache = new Map<string, AsyncSubject<any>>();
public constructor(private readonly http: HttpClient) {
}
public get<T>(url: string): AsyncSubject<T> {
if (!this.cache.has(url)) {
const subject = new AsyncSubject<T>();
this.cache.set(url, subject);
this.http.get(url)
.subscribe((data:any) => {
subject.next(data as T);
subject.complete();
});
}
return this.cache.get(url);
}
}
如果我取消订阅AsyncSubject,则我的http调用(当然)不会被取消。如何做到这一点?
答案 0 :(得分:1)
在这种情况下,您不必从http来源退订(请参阅this question)。通常,您可以使用Take运算符或flatmap进行嵌套订阅。
答案 1 :(得分:0)
获取订阅对象并取消订阅。
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { AsyncSubject, Subscription } from "rxjs";
@Injectable()
export class HttpCacheHelper {
public cache = new Map<string, AsyncSubject<any>>();
private mySubscription: Subscription;
public constructor(private readonly http: HttpClient) {
}
public get<T>(url: string): AsyncSubject<T> {
if (!this.cache.has(url)) {
const subject = new AsyncSubject<T>();
this.cache.set(url, subject);
this.mySubscription = this.http.get(url)
.subscribe((data:any) => {
subject.next(data as T);
subject.complete();
});
}
return this.cache.get(url);
}
// Use below function when required
ngOnDestroy(): void {
this.mySubscription.unsubscribe();
}
}
答案 2 :(得分:0)
您需要取消订阅源:
public get<T>(url: string): AsyncSubject<T> {
if (!this.cache.has(url)) {
const subject = new AsyncSubject<T>();
const subscription = this.http.get(url)
.subscribe((data:any) => {
subject.next(data as T);
subject.complete();
});
this.cache.set(url, {
subscribe(observer) { subject.subscribe(observer) },
unsubscribe(observer) { subscription.unsubscribe() }
});
}
return this.cache.get(url);
}
答案 3 :(得分:0)
您也可以尝试取消订阅
创建我们要用于退订的主题
private onDestroy$ = new Subject();
在您需要取消订阅的任何.subscribe()之前添加此代码
.pipe(takeUntil(this.onDestroy$))
示例
this.anyService.getData()
.pipe(takeUntil(this.onDestroy$))
.subscribe((data: any) => {
// Do work ...
});
然后像这样使用ngOnDestroy()
ngOnDestroy() {
this.onDestroy$.next();
this.onDestroy$.complete(); // Also unsubscribe from the subject itself
}
ngOnDestroy()
运行并完成主题后,使用takeUntill
进行的任何订阅也会自动退订
答案 4 :(得分:0)
我只会使用publishReplay
和refCount
:
@Injectable()
export class HttpCacheHelper {
public cache = new Map<string, Observable<yourType>>();
public constructor(private readonly http: HttpClient) {}
public get<T>(url: string): Observable<T> {
if (!this.cache.has(url)) {
const obs = this.http.get(url).pipe(
publishReplay(1),
refCount()
)
this.cache.set(url, obs);
}
return this.cache.get(url);
}
// Use below function when required
ngOnDestroy(): void {
this.mySubscription.unsubscribe();
}
}