typescript - 在 Angular 中使用 observables 进行 HTTP 请求的最佳方式是什么?
我有一个从 API 获取数据的 Angular 应用程序。所以我最初的 detail.component.ts 代码大概是这样的:
//code
getData()
{
this.http.get(url1).subscribe(data1 =>
{/*code: apply certain filter to get a filtered array out*/
this.http.get(url2).subscribe(data2 =>
{/*code: apply certain filter to get a filtered array out*/
this.http.get(url3).subscribe(data3 =>
{/*code: apply certain filter to get a filtered array out*/
})//closing third subscribe form
})//closing second subscribe form
})//closing first subscribe form
}
正如你所看到的,由于将所有这些调用相互嵌套,未来调用次数越多,一切就会变得越混乱。我做了一些研究,并得出一个想法,即 观察者(observables) 可能能解决这个问题。因此我修改了代码,现在的样子如下 - data.service.ts:
//code
getData1()
{this.data1 = this.http.get(this.url1)
return this.data1;}
getData2()
{this.data2 = this.http.get(this.url2)
return this.data2;}
getData3()
{this.data3 = this.http.get(this.url3)
return this.data3;}
detail.component.ts:
//code
ngOnInit()
{
this.dataService.getData1().subscribe(data1 =>
{/*code: apply certain filter to get a filtered array out*/
this.dataService.getData2().subscribe(data2 =>
{/*code: apply certain filter to get a filtered array out*/
this.dataService.getData3().subscribe(data3 =>
{/*code: apply certain filter to get a filtered array out*/
})//closing third subscribe form
})//closing second subscribe form
})//closing first subscribe form
}
Data1 必须先执行,因为 Data2 和 Data3 需要 Data1 过滤后的数组信息。这就是为什么我在尝试使用像 forkJoin 这样的解决方案时遇到困难的原因。所以我的问题是,这是否是一个好的解决方案,或者你是否知道有更好的方法可以让代码不那么乱,同时保持功能?
答案#1
Observable 可以提供大量的方法和工具来创建美观且易读的管道。这里有一个例子:
// my.service.ts
getData1(): Observable {
return this.httpClient.get();
}
getData2(): Observable {
return this.httpClient.post();
}
getData3(): Observable {
return this.httpClient.get();
}
my.component.ts
ngOnInit() {
this.myService.getData1().pipe(
map(data => {
// do what you want with the request answer
data.id += 1;
return data;
}),
// Pass the modified data and return the Observable for the getData2 request
switchMap(data => this.myService.getData2(data)),
// RxJs have a ton of feature to let you play with the data and the pipeline
// This will wait for 2000ms
delay(2000),
// Pass the data returns by getData2 requests to the method getData3
switchMap(data => this.myService.getData3(data)),
).subscribe(
data => console.log(data); // The result of your pipeline
)
}
这里发生了什么:
- getData1() 被调用并将返回我们 HttpRequest 的 Observable
- 我们修改之前请求的结果(增加 id)
- 我们使用修改后的结果来调用 getData2,它返回一个请求的 Observable
- 我们等待2000毫秒后继续
- 我们使用 getData2 请求的结果来调用 getData3
- 我们订阅这个管道以获取最终结果
如果你不订阅管道,它将永远不会被触发
RxJs 是一个非常庞大且很好的库,用来处理数据,但很多人并不真正知道如何有效使用它。
使用这个库你只需要遵循一件事:
- 永远不要在 Observable 中放置另一个 Observable
一些问题参考(感谢 @LingVu):
如何在 rxjs 中进行链式序列
RxJS Promise 组合(传递数据)
RxJS 序列等同于 promise.then()?
答案#2
使用 switchMap 操作符在可观察对象之间切换...
this.dataService.getData1().pipe(
switchMap(data1 => {
// do whatever with data1
return this.dataService.getData2()
}),
tap(data2 => {
// do whatever with data2
return this.dataService.getData3()
})
).subscribe()
