首页 > 解决方案 > 使用 if/else 更新 Observable 方法以使用响应式样式

问题描述

我有以下方法,我想将其更新为更具反应性的风格。它包含 if/else 逻辑。我已经读到您应该能够分解为流,对每个流应用过滤器并合并回流,但我不确定如何将其应用于以下示例。

下面的示例方法传递了一个排除标志。该方法首先调用一个 http 服务来获取一个数组。如果排除标志为真,我们需要调用另一个 http 服务来获取过滤数组所需的一些配置数据。

谢谢你的帮助。

method A(boolean excludeSomeCatagory ) : Observable<Species[]> {
  return Observable.create((observer) => {
    getSomeHttpData().subscribe((species: Species[]) => {
      if(!excludeSomeCatagory){
        observer.next(species);
        observer.complete();                                  
      }
      else {
        getSomeConfigDataFromHttp().subscribe(
          (data) => {
          filteredArray: Species[] = applyFilter(data, species);
          observer.next(filteredArray);
          observer.complete();                                                    
        });                                          
      }                             
    });
  }
}             

标签: angularrxjs

解决方案


像这样的东西会起作用:

public A(excludeSomeCategory: boolean): Observable<Species[]> {
    return getSomeHttpData().pipe(
        switchMap(species => {
            return !excludeSomeCategory
                ? of(species)
                : getSomeConfigDataFromHttp().pipe(
                    map(data => applyFilter(data, species))
                )
        })
    );
}     

总体思路是,您从 http 调用中的 observable 开始您的流,然后将其发射到您需要的形状中。你很少需要创建 observable using Observable.create(),因为 rxjs 提供了大量静态运算符来处理许多常见用例。

您还希望避免无法轻松清理的订阅(嵌套订阅)。

因此,如果我们要简单地返回getSomeHttpData();this 类型,则为Observable<Species[]>.

public A(): Observable<Species[]> {
   return getSomeHttpData();
}

显然,您需要执行更多逻辑来潜在地进行额外的 api 调用,因此我们通过管道发送 ( Species[])switchMap将为您订阅“内部可观察对象”并发出其排放。

所以,你内心switchMap想要返回一个可观察的。在您的情况下,您的条件可能只是返回接收发射或将进行另一个 http 调用。

对于您想要发出先前发射的情况,我们使用of普通值创建一个可观察的。

在另一种情况下,我们只需返回getSomeConfigDataFromHttp()本身返回可观察对象的调用。由于您想稍微转换数据,我们用它map来处理。


推荐阅读