经过一段时间的测试,阅读HttpClient的文档和源代码。
HttpClient:
https://github.com/angular/angular/blob/master/packages/common/http/src/client.ts
HttpXhrBackend :
https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts
HttpClientModule
:https://indepth.dev/exploring-the-httpclientmodule-in-angular/
Angular大学:https : //blog.angular-university.io/angular-http/
这种特定类型的Observable是单值流:如果HTTP请求成功,则这些Observable将仅发出一个值,然后完成
以及整个“我是否需要”退订问题的答案?
这取决于。
Http调用Memoryleaks不是问题。问题是回调函数中的逻辑。
例如:路由或登录。
如果您的呼叫是登录呼叫,则不必“取消订阅”,但需要确保用户是否离开页面,在没有用户的情况下可以正确处理响应。
this.authorisationService
.authorize(data.username, data.password)
.subscribe((res: HttpResponse<object>) => {
this.handleLoginResponse(res);
},
(error: HttpErrorResponse) => {
this.messageService.error('Authentication failed');
},
() => {
this.messageService.info('Login has completed');
})
从烦人到危险
现在,想象一下,网络速度比平时慢,通话时间要长5秒钟,并且用户离开登录视图并进入“支持视图”。
该组件可能不是活动的,但是订阅。在响应的情况下,用户将被突然重新路由(取决于您的handleResponse()实现)。
这是不是好。
还可以想象用户离开PC,以为他尚未登录。但是您的逻辑使用户登录,现在您遇到了安全问题。
如果不取消订阅该怎么办?
让您根据视图的当前状态进行调用:
public isActive = false;
public ngOnInit(): void {
this.isActive = true;
}
public ngOnDestroy(): void {
this.isActive = false;
}
用户.pipe(takeWhile(value => this.isActive))
确保仅在视图处于活动状态时才处理响应。
this.authorisationService
.authorize(data.username, data.password).pipe(takeWhile(value => this.isActive))
.subscribe((res: HttpResponse<object>) => {
this.handleLoginResponse(res);
},
(error: HttpErrorResponse) => {
this.messageService.error('Authentication failed');
},
() => {
this.messageService.info('Login has completed');
})
但是,如何确定订阅不会引起内存泄漏呢?
您可以记录是否应用了“ teardownLogic”。
当订阅为空或取消订阅时,将调用订阅的teardownLogic。
this.authorisationService
.authorize(data.username, data.password).pipe(takeWhile(value => this.isActive))
.subscribe((res: HttpResponse<object>) => {
this.handleLoginResponse(res);
},
(error: HttpErrorResponse) => {
this.messageService.error('Authentication failed');
},
() => {
this.messageService.info('Login has completed');
}).add(() => {
// this is the teardown function
// will be called in the end
this.messageService.info('Teardown');
});
您不必取消订阅。您应该知道逻辑中是否存在问题,这可能会导致订阅出现问题。并照顾他们。在大多数情况下,这不会成为问题,但是特别是在诸如自动处理之类的关键任务上,您应该注意意外的行为,无论是否带有“取消订阅”或其他逻辑(例如管道或条件回调函数)。
为什么不总是退订?
假设您提出了放置或发布请求。服务器以任何一种方式接收消息,只是响应需要一段时间。取消订阅,不会撤消帖子或放置。但是,当您退订时,您将没有机会处理响应或通知用户,例如通过对话框或Toast / Message等。
Wich使用户相信未完成放置/发布请求。
因此,这取决于。这是您的设计决策,如何处理此类问题。