参数更改后订阅仍然有效
Subscription still live after the parameter changed
我有一个订阅来获取路由附带的参数,在该订阅中(成功后)我正在从同一服务调用另一个订阅以获取消息详细信息。
问题是:当参数更改时,与旧参数相关的订阅仍然存在。
this.routes.params.subscribe(param => {
this.isLoading = true;
this.messageId = param['id'];
this.inboxService.getMessageDetail(toNumber(this.messageId)).subscribe((dat) => {
this.initMessageDetails(dat);
})
})
这就是不鼓励嵌套订阅的确切原因。它会导致多个订阅,其中一些可能未关闭。
您需要使用更高阶的映射运算符,例如带有参数 1
的 swithcMap
to map from one observable to another and take
运算符,以在首次发射后关闭第一个 observable。
import { take, switchMap } from 'rxjs/operators';
this.routes.params.pipe(
take(1), // <-- complete after first emission
switchMap(param => { // <-- map to another observable
this.isLoading = true;
this.messageId = param['id'];
return this.inboxService.getMessageDetail(toNumber(this.messageId));
}
).subscribe(
(dat) => {
this.initMessageDetails(dat);
},
(error: any) => {
// handle errors
}
);
这是 switchMap
运算符的完美用例!它为父级的每个发射订阅子 Observable,取消订阅该子 Observable 的先前实例。
只要有可能,您应该避免在 subscribe
回调中放置逻辑,尤其是当它涉及订阅另一个 Observable 时。使用 RxJS Observables 时,使用它们的 pipe
运算符:
this.routes.params.pipe(
tap(params => {
this.isLoading = true;
this.messageId = params['id'];
}),
switchMap(params => this.inboxService.getMessageDetail(toNumber(this.messageId))),
tap(dat => this.initMessageDetails(dat))
).subscribe();
您还应该实现某种取消订阅逻辑,以确保您的 Observable 在组件关闭时关闭(例如,使用 takeUntil
运算符和在 ngOnDestroy()
中发出的 Subject)。 =16=]
我有一个订阅来获取路由附带的参数,在该订阅中(成功后)我正在从同一服务调用另一个订阅以获取消息详细信息。 问题是:当参数更改时,与旧参数相关的订阅仍然存在。
this.routes.params.subscribe(param => {
this.isLoading = true;
this.messageId = param['id'];
this.inboxService.getMessageDetail(toNumber(this.messageId)).subscribe((dat) => {
this.initMessageDetails(dat);
})
})
这就是不鼓励嵌套订阅的确切原因。它会导致多个订阅,其中一些可能未关闭。
您需要使用更高阶的映射运算符,例如带有参数 1
的 swithcMap
to map from one observable to another and take
运算符,以在首次发射后关闭第一个 observable。
import { take, switchMap } from 'rxjs/operators';
this.routes.params.pipe(
take(1), // <-- complete after first emission
switchMap(param => { // <-- map to another observable
this.isLoading = true;
this.messageId = param['id'];
return this.inboxService.getMessageDetail(toNumber(this.messageId));
}
).subscribe(
(dat) => {
this.initMessageDetails(dat);
},
(error: any) => {
// handle errors
}
);
这是 switchMap
运算符的完美用例!它为父级的每个发射订阅子 Observable,取消订阅该子 Observable 的先前实例。
只要有可能,您应该避免在 subscribe
回调中放置逻辑,尤其是当它涉及订阅另一个 Observable 时。使用 RxJS Observables 时,使用它们的 pipe
运算符:
this.routes.params.pipe(
tap(params => {
this.isLoading = true;
this.messageId = params['id'];
}),
switchMap(params => this.inboxService.getMessageDetail(toNumber(this.messageId))),
tap(dat => this.initMessageDetails(dat))
).subscribe();
您还应该实现某种取消订阅逻辑,以确保您的 Observable 在组件关闭时关闭(例如,使用 takeUntil
运算符和在 ngOnDestroy()
中发出的 Subject)。 =16=]