我想我已经阅读了 100 多篇关于该主题的文章,但我仍然无法弄清楚如何在 Angular 6 中使用 rxjs 链接两个 HttpClient 调用。
假设我有一个具有该签名的服务:
GeoService {
getState(): Observable<string> {
return this.http.get<string>(stateURL);
}
getCities(state: string): Observable<string[]> {
return this.http.get<string[]>(citiesURL + state);
}
}
我一生都无法弄清楚如何获取组件中的州和相应的城市列表:
import { Observable } from 'rxjs';
import { map, flatMap, mergeMap, filter, switchMap } from 'rxjs/operators';
...
ngOnInit() {
this.svc.getState().
pipe(map((state) => {
this.state = state;
return this.svc.getCities(state);
}),
mergeMap((cities) => this.cities = cities))
).subscribe(console.log('done'));
上面的代码是我以我能想到的各种方式组合管道/映射/合并映射/订阅的 20 次随机尝试之一......如果有一个有效的示例,我将非常感激:)
谢谢!
编辑:“可能重复”的帖子都不包含有效的实际示例
第 21 次尝试是正确的;-)
this.svc.getState().
pipe(mergeMap((state) => {
this.state = state;
return this.svc.getCities(state);
}),
tap((cities) => this.cities = cities)))
.subscribe(() => console.log('done'));
链式 Observable 进入内部
mergeMap
。您可以将其视为:
首先,映射传入的通知到一个Observable,然后合并产生的“内部”Observable到“外部”Observable
此外,如果您打算更改外部状态,请使用
tap
而不是 map
。
你就快到了:
this.svc.getState().
pipe(
mergeMap((state) => {
return this.svc.getCities(state).pipe(map(cities => {
return { state: state, cities: cities }
}));
}),
).subscribe(stateAndCities => console.log(stateAndCities));
我建议你阅读这篇文章:
https://blog.strongbrew.io/rxjs-best-practices-in-angular/#using-pure-functions
它还解释了为什么你不应该与 rxjs 运算符中的全局变量交互。
你可以做这样的事情
this.svc.getState().pipe(
tap(state=>this.state=state),
switchMap(this.svc.getCities))
.subscribe(cities=>{
//got the cities
})
map 运算符用于转换发射值,但 tap 运算符用于在不修改可观察值的发射值的情况下执行某些操作。
注意 switchMap(this.svc.getCities) 相当于 switchMap(state=>this.svc.getCities(state)