Выполнение вложенных вызовов API с использованием RxJS на основе условия с использованием оператора iif, что приводит к превышению максимального размера стека вызовов

Я пытаюсь использовать условный оператор rxjs. Я проверяю, хранятся ли данные в local storage, верните это, если нет, сделайте 2 HTTP-вызова, чтобы получить необходимые данные и вернуть их.

Вот мой код:

// making nested API calls
    loggedInUserDetails$ = this._getPoid().pipe(
      concatMap((userData: any) => this._userData(userData)),
      map((userDetails: any) => userDetails.legalName.nameLastFirst),
      tap((user: string) => this._storage.saveUserInStorage(user)),
      catchError(() => of('some dummy name')),
   );

  storedUserData$ = of(this._storage.getUserFromStorage());

  loggedInUsername$ = of(this._storage.getUserFromStorage()).pipe(
    mergeMap((username: string) =>
      iif(
        () => Boolean(username),
        this.storedUserData$,
        this.loggedInUserDetails$,
      ),
    ),
    tap(console.log),
  ); 


 loggedInUsername$.subscribe(data => console.log(data)); 

Приведенный выше код возвращает Превышен максимальный размер стека вызовов

Observable.js: 54 RangeError: Превышен максимальный размер стека вызовов в MergeMapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / OuterSubscriber.js.OuterSubscriber.notifyError (OuterSubscriber.js: 12) в InnerSubscriber_modules ../ rxjs / _esm5 / internal / InnerSubscriber.js.InnerSubscriber._error (InnerSubscriber.js: 18) в InnerSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber.error (Subscriber.js: 59) в TapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Operators / tap.js.TapSubscriber._error (tap.js: 61) в TapSubscriber.push ../ node_modules / rxjs / _esm5 / internal / Subscriber.js.Subscriber .error (Subscriber.js: 59) в


person Pritam Bohra    schedule 01.06.2020    source источник
comment
почему вы повторяете of (this._storage.getUserFromStorage ())? я думаю, что истинное состояние iif переходит в бесконечный цикл ... но нужны более подробные сведения   -  person Francesco Bellavita    schedule 02.06.2020
comment
Не могли бы вы создать StackBlitz?   -  person Andrei Gătej    schedule 02.06.2020


Ответы (1)


Я бы не сказал, что mergeMap является подходящим оператором в этом сценарии. Вы не хотите объединять наблюдаемые объекты, а вместо этого переключаете их на другое. Попробуйте с оператором switchMap.

loggedInUsername$ = of(this._storage.getUserFromStorage()).pipe(
  switchMap((username: string) =>
    iif(
      () => Boolean(username),
      this.storedUserData$,
      this.loggedInUserDetails$,
    ),
  ),
  tap(console.log),
);
person Michael D    schedule 01.06.2020