Угловая наилучшая практика с наблюдаемыми изменениями значений

#angular #async-await #rxjs #observable

Вопрос:

в нашем текущем проекте мы используем наблюдаемое, и если значение изменится, нам придется выполнять другие вызовы api. Например, что-то вроде этого ( authorizedModules$ является наблюдаемым):

 ngOnInit(): void {
    this.authorizedModules$
      .pipe(
        takeUntil(this.onDestroy$),
        switchMap(async () => this.load())
      ).subscribe();
}

async load(): Promise<void> {
    const foo: boolean = await this.fooService.isFoo().toPromise();
    
    if (!foo) {
      return;
    }
    
    const fooA: Foo[] = await this.authorizedModules$.pipe(take(1)).toPromise();
    
    if (!fooA || fooA.length === 0) {
      return;
    }
    
    this.fooB = await this.fooService.getFoo(fooA);
    ....  
}
 

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

Ответ №1:

Я бы сказал, что нет необходимости преобразовывать наблюдаемые в обещания. Вы можете сопоставлять одно наблюдаемое с другим, используя оператор сопоставления более высокого порядка (например concatMap ), и использовать filter оператор для продолжения только при соблюдении определенных условий.

Попробуйте сделать следующее

 ngOnInit(): void {
  this.authorizedModules$.pipe(
    concatMap(() => this.fooService.isFoo()),
    filter(foo => !!foo),
    concatMap(() => this.authorizedModules$.pipe(take(1))),
    filter(fooA => !!fooA amp;amp; fooA.length != 0),
    concatMap(fooA => this.fooService.getFoo(fooA)),
    takeUntil(this.onDestroy$),
  ).subscribe({
    next: (res: any) => {
      // handle response
    },
    error: (error: any) => {
      // handle error
    }
  });
}