Rxjs 在Angular 6中链接HttpClient调用
我想我已经阅读了100多篇关于这个主题的帖子,但我仍然不知道如何在Angular 6中使用rxjs链接两个HttpClient调用 假设我有一个签名为的服务:Rxjs 在Angular 6中链接HttpClient调用,rxjs,angular6,Rxjs,Angular6,我想我已经阅读了100多篇关于这个主题的帖子,但我仍然不知道如何在Angular 6中使用rxjs链接两个HttpClient调用 假设我有一个签名为的服务: GeoService { getState(): Observable<string> { return this.http.get<string>(stateURL); } getCities(state: string): Observable<
GeoService {
getState(): Observable<string> {
return this.http.get<string>(stateURL);
}
getCities(state: string): Observable<string[]> {
return this.http.get<string[]>(citiesURL + state);
}
}
上面的代码是我20次随机尝试中的一次,尝试以我能想到的任何方式组合pipe/map/mergeMap/subscribe。。。请举一个有效的例子:)
谢谢
编辑:没有一篇“可能重复”的文章包含一个实际可行的例子第21次尝试应该是正确的;-) 链接的可观察对象进入
mergeMap
内部。你可以这样想:
首先,将传入的notifaction映射到一个可观察对象,然后将所得的“内部”可观察对象合并到“外部”可观察对象中
另外,如果您想更改外部状态,请使用
点击
而不是映射。您可以这样做
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)您就快到了:
this.svc.getState().
pipe(
mergeMap((state) => {
return this.svc.getCities(state).pipe(map(cities => {
return { state: state, cities: cities }
}));
}),
).subscribe(stateAndCities => console.log(stateAndCities));
我建议您阅读这篇文章:
它还解释了为什么您不应该在rxjs操作符中与全局变量交互。您可以通过将第二个(和第三个等)调用放在订阅的res部分(如果不需要res值,则完成)中来链接它们。例如:this.svc.getState().subscribe(res=>{this.svc.getCities(res).subscribe(res=>{},err=>{},()=>{},()=>{},err=>{},()=>{}
可能重复@ggradnig我不这么说,你可以从http调用的subscribe部分this.svc.getState().pipe(mergeMap(state=>this.svc.getCities(state)).subscribe(…)
@martin你需要订阅getCities()
call-else它实际上不会进行http调用您正在rxjs运算符中分配一个全局变量。这有点反模式…全局有效?在哪里?这个.state?您的rxjs运算符最好使用纯函数。好的,但是tap(新版本的“do”)运算符是针对副作用而设计的。但它仍然是一种反模式;),在这种情况下,使用标准的map运算符很容易解决。谢谢,经过测试,它可以正常工作。我接受了Kevin的答案,因为它不涉及中间对象。我确实理解你关于纯函数的观点,但我不喜欢为了把结果带到管道的末端而必须聚合成一个无意义的对象。对我来说,一个自然的模式是:var response=this.svc.getState();response.subscribe(state=>this.state=state);管道(map(state=>getProviders(state))).subscribe(cities=>…);伪代码,我受够了那个API,所以我没有勇气测试它…那会起作用,但是你的响应对象必须是一个ReplaySubject(或者是一个应用publishReplay()的可观察对象)。谢谢,我测试了我们的解决方案,它起作用了。我接受了Kevins的答案,因为它更简单,并且不会从mergeMap内部改变状态。
this.svc.getState().pipe(
tap(state=>this.state=state),
switchMap(this.svc.getCities))
.subscribe(cities=>{
//got the cities
})
this.svc.getState().
pipe(
mergeMap((state) => {
return this.svc.getCities(state).pipe(map(cities => {
return { state: state, cities: cities }
}));
}),
).subscribe(stateAndCities => console.log(stateAndCities));