使用 if/else 更新 Observable 方法以使用反应式风格

dec*_*che 1 rxjs angular

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

下面的示例方法传递排除标志。该方法首先调用 http 服务来获取数组。如果排除标志为 true,则我们需要调用另一个 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();                                                    
        });                                          
      }                             
    });
  }
}             
Run Code Online (Sandbox Code Playgroud)

Biz*_*Bob 5

像这样的事情会起作用:

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

总体想法是,您使用 http 调用中的可观察值来启动流,然后将其发射传输到您需要的形状。您很少需要创建可观察的使用,Observable.create()因为 rxjs 提供了大量处理许多常见用例的静态运算符。

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

因此,如果我们简单地返回,getSomeHttpData();这将是 类型Observable<Species[]>

public A(): Observable<Species[]> {
   return getSomeHttpData();
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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