经过一段时间的测试,阅读文档和 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/
角大学: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() 实现)。
这不好。
还可以想象用户离开电脑,相信他还没有登录。但是您的逻辑使用户登录,现在您遇到了安全问题。
不退订可以做什么?
让您根据视图的当前状态调用:
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');
});
您不必取消订阅。您应该知道您的逻辑是否存在问题,这可能会导致您的订阅出现问题。并照顾好他们。在大多数情况下,这不是问题,但特别是在自动化等关键任务中,您应该注意意外行为,无论是“取消订阅”还是其他逻辑,如管道或条件回调函数。
为什么不总是退订?
想象一下,您提出了一个 put 或 post 请求。服务器以任何一种方式接收消息,只是响应需要一段时间。退订,不会撤消帖子或放置。但是当您取消订阅时,您将没有机会处理响应或通知用户,例如通过对话框或 Toast/Message 等。
这使用户相信 put/post 请求没有完成。
所以这取决于。如何处理这些问题是您的设计决定。