我想知道我是否使用Observable.subscribe()太多次了 .
在我的组件类中,我有一个函数loadData() . 它调用另一个函数this.service.getData(),它使用HttpClient.get()来执行对服务器的HTTP请求 .
目前在我的函数loadData()中,我订阅了this.service.getData()的结果 .
每次用户点击“更新”按钮时,我想调用我的函数loadData() .
这个问题
-
如果每次需要执行HTTP请求时都调用我的函数 loadData() ,我是否会创建尽可能多的订阅者?
-
存在内存泄漏的风险吗?
-
如果是这样,你知道我应该如何重构我的代码吗?
答案
-
我发现了这个帖子Is it necessary to unsubscribe from observables created by Http methods?
-
它解释了Angular代码在HTTP请求之后实际调用了observable.complete(),并且有延迟
-
所以我修改了下面的代码来检查这个事实,测试证实它是真的
代码示例
private loadData() {
this.loading = true;
const subscription = this.service.getData()
.pipe(
// console.log() with a delay added for test - START
map(val => {
window.setTimeout(() => {
// This will print true.
console.log('After delay: Is Subscriber closed?', subscription.closed);
}, 10);
return val;
}),
// console.log() with a delay added for test - END
takeUntil(this.ngUnsubscribe))
.subscribe(data => {
this.data = data;
// This will print false.
console.log('Is Subscriber closed?', subscription.closed);
},
error => {
console.error(error);
throw error;
},
() => {
this.loading = false;
});
}
getData(): Observable<DataObject> {
const uri = encodeURI(this.configService.getUri());
const headers = new HttpHeaders();
if (this.pipelineEtag) {
headers.set('If-None-Match', this.pipelineEtag);
}
return this.http.get(uri, {
headers: headers,
observe: 'response'
}).pipe(
map(resp => this.processResponse(resp)),
catchError(error => this.handleError(error, this.envProduction))
);
}
3 回答
每次HTTP调用返回一个值时,Observable都会完成 . 所以在服务中做这样的事情是安全的
然后打电话
你甚至可以调用exhaustMap或switchMap来控制Observable流,以免“提示”太多时间服务器
这是正确的用法,创建多个订阅者没有风险 .
从文档:
Source
技术细节是,一旦Http请求完成,就会调用observable的
.complete
方法,该方法会杀死所有当前订阅者 . 这意味着您的订户已创建,使用,并立即被丢弃 .所以最后
我发现了这个帖子:Is it necessary to unsubscribe from observables created by Http methods?
它解释了Angular代码在HTTP请求之后实际调用了observable.complete(),并且有延迟
所以我修改了下面的代码来检查这个事实,测试证实它是真的