Typescript - я не могу сделать мой универсальный наблюдаемый преобразователь асинхронным - PullRequest
0 голосов
/ 27 февраля 2019

Чтобы сохранить мой код в чистоте, я хочу создать универсальный метод для возврата данных из наблюдаемых, которые также отписываются после возвращения данных.Он возвращает данные, но часто возвращает данные слишком поздно, в то время как код переместился, что не очень хорошо работает на странице входа в систему ...

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."отписался от, чтобы предотвратить утечку памяти, однако большая часть кода выглядит так, как показано ниже, и, если не считать превращения его в переменную, я не знаю ни одного способа отписаться.

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

Является ли эта идея наблюдаемого резольвера просто плохой идеей или есть более чистый способ сделать это?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Вы правы в том, что наблюдаемые подписки необходимо очистить, иначе возможны утечки памяти.Но в таких случаях, как ваш login пример, они автоматически очищаются:

Если наблюдаемое завершается (успешно или с ошибкой), тогда подписка автоматически отменяется, и вам не нужно об этом беспокоиться.Таким образом, в вашем примере, когда вы вызываете службу входа в систему, это довольно безопасное предположение, что эта служба возвращает наблюдаемое, которое будет генерировать только одно значение, а затем завершится.Таким образом, как только вы наблюдаете результат входа в систему, подписка удаляется, и вы готовы к работе.

Совет по очистке ваших подписок действительно применим в тех случаях, когда вы подписываетесь на наблюдаемое, которое может вернуть много значений, и выможет захотеть / нужно прекратить слушать до того, как все они прибудут.В этих случаях ответ от другого @Brandon обеспечивает хороший шаблон для отписки.

0 голосов
/ 27 февраля 2019

Вы всегда можете создать свойство модели представления для подписки, от которой вы можете отказаться от подписки:

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 также откажется от вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...