首页 > 解决方案 > 具有可观察值更改的 Angular 最佳实践

问题描述

在我们当前的项目中,我们使用 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);
    ....  
}

我不确定这是否是一种反模式,或者至少是一个好的解决方案,因为我们混合了 Observables 和 Promises。那么处理这样的事情的最佳方法是什么?

标签: angularasync-awaitrxjsobservable

解决方案


我想说没有必要将 observables 转换为 Promise。您可以使用高阶映射运算符(如concatMap)从一个可观察对象映射到另一个对象,并仅在满足特定条件时使用filter运算符继续。

尝试以下

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

推荐阅读