angular - Angular:每次我需要更新时,我应该订阅()到 http.get()吗?
问题描述
我想知道我是否多次使用 Observable.subscribe() 。
在我的组件类中,我有一个函数 loadData()。它调用另一个函数 this.service.getData() 使用 HttpClient.get() 向服务器执行 HTTP 请求。
目前在我的函数 loadData() 中,我订阅了 this.service.getData() 的结果。
每次用户单击“更新”按钮时,我都想调用我的函数 loadData()。
问题
- 如果我每次需要执行 HTTP 请求时都调用我的函数loadData() ,我会创建尽可能多的订阅者吗?
- 有内存泄漏的风险吗?
- 如果是这样,你知道我应该如何重构我的代码吗?
答案
- 我发现了这篇其他帖子是否有必要取消订阅由 Http 方法创建的可观察对象?
- 它解释了 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))
);
}
解决方案
每次 HTTP 调用返回一个值时,Observable 就完成了。所以在服务中做这样的事情是安全的
loadData() {
return this.http.get<Data>(dataUrl).pipe(
// tap(data => console.log(data)), // eyeball results in the console
catchError(err => this.handleError(err))
);
}
然后打电话
this.service.loadData().subscribe((data:Data) => do somthing)
你甚至可以调用 exhaustMap 或 switchMap 来控制 Observable 流,以免“提示”服务器太多时间
推荐阅读
- laravel - 带有 ssl 和 nginx 的 Laravel-websockets
- apache-flink - 在 Flink 状态查询中,查询的结果是读未提交还是读提交
- javascript - 如何在另一个组件角度10中渲染组件
- vba - 从外部非 Office 程序发送邮件时如何触发 Outlook 的 Application_ItemSend?
- javascript - 从 .getJSON 的结果中设置变量值
- json - 强制 FACEBOOK GRAPH API 显示个人资料 url 图片,而不是下载它
- typescript - 如何在 Vuex 的操作中使用 axios 获取 RestAPI 数据?
- jquery - 来自 API 请求的 JQUERY 数据表
- python - Discord.py:想要将 message.content 读取为小写,.lower() 不起作用
- node.js - 节点 AWS Lambda 没有执行一些异步代码