我想知道是否有必要从使用运算符管道的一组HttpClient可观测到的用forkJoin([..])制作的可观测数据中取消订阅HttpClient?
我读过关于forkJoin(..)自动取消订阅的文章,但我不知道用shareReplay(..)运算符传递管道时是否是相同的情况,因为我读到这一次如果被误用会导致内存泄漏问题。
下面的示例用于缓存Http请求结果,下面是我的代码块:
服务:
@Injectable()
export class HttpcatcherService {
codeNafsObservable$: Observable<any>;
constructor(private positionservice: PositionserviceService) {}
getAllEntities(refresh?: boolean): Observable<any> {
if (!this.codeNafsObservable$ || refresh) {
this.codeNafsObservable$ = forkJoin([
this.positionservice.getPosts(), // returns Observable
this.positionservice.getComments(), // returns Observable
]).pipe(
map((result) => {
return {
secondNaf: result[0],
thirdNaf: result[1],
};
}),
shareReplay(1)
);
}
return this.codeNafsObservable$;
}
}我的组件(知道我在不同组件中使用相同的方式/逻辑):
@Component({
selector: 'hello',
templateUrl: './hello.component.html',
styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements OnInit {
constructor(private httpCat: HttpcatcherService) {}
ngOnInit(): void {
this.httpCat
.getAllEntities()
.subscribe(
(result) => {
console.log(result);
});
}
}发布于 2022-03-23 20:34:04
我认为使用forkJoin和shareReplay不会导致任何内存泄漏问题。原因如下:
forkJoin的形式传入时,complete会发出通知。在这种情况下,由于传递给forkJoin的可观察到的调用与http调用相关,所以它们在http调用返回后就完成了。因此,当两个http调用都返回时,forkJoin创建的可观察到的消息就会通知并完成。shareReplay的作用是创建一个内部缓存,确保任何订阅都将得到上游通知的最后一个值。在这种情况下,上游通知的最后一个值是forkJoin创建的可观察值所通知的唯一值。当可观察到的源是无限流(例如用shareRepley创建的流)时,内存泄漏的风险,或者至少是使用interval不受控制地执行代码的风险。在这种情况下,shareReplay创建了一个可观察的、从未完成的可观察性,即使没有订阅服务器,除非ShareReplayConfig的refCount属性设置为true。
这个行为在详细的在文件中中得到了解释。
在任何情况下,这都不是您运行的风险,因为您所拥有的源只会发出一次,然后完成。
发布于 2022-03-23 20:37:25
在RxJS 7中,shareReplay(1)是一个包含以下参数的共享包装器:
share({
connector: () => new ReplaySubject(1),
resetOnComplete: false,
resetOnError: false,
resetOnRefCountZero: false
})如果您希望更好地控制shareReplay的工作方式,请使用share,并根据需要设置配置选项。
例如,如果将resetOnRefCountZero设置为true,则当不再有任何订阅者时,内部ReplaySubject将被取消订阅。
https://stackoverflow.com/questions/71592457
复制相似问题