首页 > 解决方案 > 打字稿 - 我不能让我的通用可观察解析器异步

问题描述

为了让我的代码更简洁,我想创建一个通用方法来从可观察对象返回数据,一旦数据返回,该方法也会取消订阅。它返回数据,但是当代码继续移动时,它经常返回数据太晚,这在登录页面上效果不佳......

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;
}

当我将 async 添加到函数头时,我得到“Type T is not a valid async function return type in 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');
};

这种可观察解析器的想法只是一个坏主意还是有更清洁的方法来做到这一点?

标签: angulartypescriptrxjs

解决方案


您始终可以为可以取消订阅的订阅创建视图模型属性:

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();
  }

}

作为替代方案,您可以在组件被销毁时使用 Subject 取消订阅。有关示例,请参见:https ://medium.com/@stodge/ngrx-common-gotchas-8f59f541e47c。

当然,| async管道也会为您退订。


推荐阅读