为了保持代码的整洁,我想创建一个通用方法来从可观察对象返回数据,一旦返回数据,该对象也将取消订阅。它返回数据,但是在代码移动后通常返回时为时已晚,这在登录页面上无法正常工作...
import { Observable, throwError } from "rxjs";
import { Type } from "@angular/compiler";
export async function resolveObseravableData<T>
(obs: Observable<any>, classReference: { new (): T}) : T {
let instance = new classReference();
let obsRes = await obs.subscribe((data: T) => { instance = data; },
(err: Error) => {
throwError(`Error in utility.functions.resolveObseravableData: ${err.message}`); })
obsRes.unsubscribe();
return instance;
}
当我向函数头添加异步时,我得到“类型T在ES5 / ES3中不是有效的异步函数返回类型”,因为它没有引用Promise兼容的构造函数值。”
我是angular / typescript的新手,我读到应取消订阅Observables以防止内存泄漏,但是下面的代码看起来很多,并且缺少将其转换为变量的方法,我对此一无所知退订。
this.authService.login(this.f.email.value, this.f.password.value).subscribe(
data => {
if (data) {
console.log('logged in ' + this.authService.currentUser.email);
this.router.navigate([this.returnUrl]);
} else {
console.log('currrent user is null');
}
},
err => {
console.log('error on login' + err.message);
});
使用解析器替换以上内容:
if (resolveObseravableData(
this.authService.login(this.f.email.value, this.f.password.value), Boolean)) {
this.router.navigate([this.returnUrl]);
} else {
console.log('currrent user is null');
};
这种可观察的分解器的想法只是一个坏主意,还是有一种更清洁的方式来做到这一点?
答案 0 :(得分:1)
您始终可以为您可以取消订阅的订阅创建视图模型属性:
import { Subscription } from 'rxjs;
@Component({...})
export class YourComponent implements OnInit, OnDestroy {
subscription: Subscription;
constructor (
private yourService: YourService,
) {}
ngOnInit(): void {
this.subscription = this.yourService.yourObservable$.subscribe(state => {...});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
作为替代方案,可以在组件销毁时使用“主题”退订。有关示例,请参见:https://medium.com/@stodge/ngrx-common-gotchas-8f59f541e47c。
当然,| async
管道也将为您退订。
答案 1 :(得分:0)
您是正确的,需要清理可观察的订阅,否则您可能会发生内存泄漏。但是在类似您的login
示例的情况下,它们会自动清理自身:
如果可观察对象完成(成功或有错误),则订阅将自动释放,您无需担心。因此,在您调用登录服务的示例中,一个相当安全的假设是该服务返回一个可观察值,该可观察值只会产生一个值,然后才能完成。因此,一旦您观察到登录结果,订阅就会被处理,您就可以进行了。
清理订阅的建议确实适用于那些您订阅可观察对象的情况,该可观察对象可能返回许多值,并且您可能希望/需要在它们全部到达之前停止侦听。在这种情况下,另一个@Brandon的the answer提供了一种很好的退订模式。