用if/else更新Observable方法,使用响应式样式



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

下面的示例方法传递了一个排除标志。该方法首先调用HTTP服务以获取数组。如果exclude标志为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();                                                    
});                                          
}                             
});
}
}             

可以这样做:

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

总体思路是,你用http调用中的一个可观察对象开始你的流,然后把它发射成你需要的形状。你很少需要使用Observable.create()创建一个可观察对象,因为rxjs提供了大量的静态操作符来处理许多常见的用例。

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

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

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

显然,你有一些更多的逻辑,你想做一个潜在的额外的api调用,所以我们管道发射(Species[])到switchMap,这将订阅一个"内部可观察对象";为你而排放的排放物。

所以,在switchMap内部,你想返回一个可观察对象。在您的情况下,您有一个条件,可以简单地返回接收发射或将进行另一个http调用。

当你想发出先前的发射时,我们使用of从普通值中创建一个可观察对象。

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

直接返回Observable,并使用SwitchMap

method A(boolean excludeSomeCatagory ) : Observable<Species[]> {
return getSomeHttpData().pipe(
switchMap((species) => {
if(!excludeSomeCatagory){
return of(species)
} else {
return getSomeConfigDataFromHttp().pipe(
map(data => {
return applyFilter(data, species)
})
)
}
})
)
}

最新更新