并行处理来自 angular 8 的多个 API 请求
Handle multiple API requests parallel from angular 8
我需要从我的 angular 应用程序并行调用多个 API 请求,我需要分别获取每个响应(需要对每个响应执行一些不同的操作)并且我还需要跟踪当所有请求完成执行时
例如,我有一个请求 arr1[request1,request2,request3,request4] 的数组,每个请求将花费不同的时间来获得 response.so 我需要执行不同的操作,例如 actn1、actn2、actn3 ..etc 根据 response.i 需要以 FCFS 方式调用每个动作。某些请求将比其他请求更快地完成执行,因此每当我收到每个请求的响应时,我需要调用相应的操作,最后在获得所有响应后我还需要调用 finalAction。
通过使用 forkJoin 我能够执行我的 finalAction(在完成所有请求执行后这必须工作)但是我不知道当响应来自服务器时我将如何执行每个响应操作
尝试使用 combineLatest()
确保每个可观察对象至少发出 1 个值。
您可以使用 .pipe()
和 tap()
让任何可观察对象采取单独的行动。
combineLatest([
req1.pipe(tap(result => {
/* take action */
})),
req2.pipe(tap(result => {
/* take another action */
})),
req3.pipe(tap(result => {
/* take a super action */
})),
req4.pipe(tap(result => {
/* do nothing maybe */
}))
]).subscribe((resultArray) => {
/* take the final action as all of the observables emitted at least 1 value */
})
combineLatest
参考:https://www.learnrxjs.io/learn-rxjs/operators/combination/combinelatest
tap
参考:https://www.learnrxjs.io/learn-rxjs/operators/utility/do
更新
如果你有一个动态长度的数组,你可以在 combineLatest()
中使用 Array.map()
来迭代 observables
const requests = [req1,req2,req3,..., reqN]
combineLatest(
requests.map(req => req.pipe(tap(res => handleResponse(res))))
).subscribe();
const handleResponse = (response) => { /*do something*/ }
这是一个有效的 stackblitz 项目:https://stackblitz.com/edit/rxjs-a16kbu
我从@Harun Yilmaz 那里得到了解决方案post,只是我在这里添加它以供其他人参考。
getDataFromApi(url) {
let httpOptions={};
let param=["CAL3","CAL2","CAL1"];//dynamic parameter(CAL1:8sec,CAL2:5s,CAL3:12s)
let httpArray=[];
for(let i=0;i<param.length;i++){
httpArray.push(this.http.post<any>(url + `/PostDataSet?Id=${param[i]}`, {}, httpOptions))
}
const handleResponse = (response) => {
//here i am getting each response in a first come first manner
console.log(response.Table[0].Output);
}
const combineResponse =combineLatest(
httpArray.map(req => req.pipe(tap(handleResponse)))
)
return combineResponse;
}
//output
CAL2
CAL1
CAL3
我需要从我的 angular 应用程序并行调用多个 API 请求,我需要分别获取每个响应(需要对每个响应执行一些不同的操作)并且我还需要跟踪当所有请求完成执行时
例如,我有一个请求 arr1[request1,request2,request3,request4] 的数组,每个请求将花费不同的时间来获得 response.so 我需要执行不同的操作,例如 actn1、actn2、actn3 ..etc 根据 response.i 需要以 FCFS 方式调用每个动作。某些请求将比其他请求更快地完成执行,因此每当我收到每个请求的响应时,我需要调用相应的操作,最后在获得所有响应后我还需要调用 finalAction。
通过使用 forkJoin 我能够执行我的 finalAction(在完成所有请求执行后这必须工作)但是我不知道当响应来自服务器时我将如何执行每个响应操作
尝试使用 combineLatest()
确保每个可观察对象至少发出 1 个值。
您可以使用 .pipe()
和 tap()
让任何可观察对象采取单独的行动。
combineLatest([
req1.pipe(tap(result => {
/* take action */
})),
req2.pipe(tap(result => {
/* take another action */
})),
req3.pipe(tap(result => {
/* take a super action */
})),
req4.pipe(tap(result => {
/* do nothing maybe */
}))
]).subscribe((resultArray) => {
/* take the final action as all of the observables emitted at least 1 value */
})
combineLatest
参考:https://www.learnrxjs.io/learn-rxjs/operators/combination/combinelatest
tap
参考:https://www.learnrxjs.io/learn-rxjs/operators/utility/do
更新
如果你有一个动态长度的数组,你可以在 combineLatest()
中使用 Array.map()
来迭代 observables
const requests = [req1,req2,req3,..., reqN]
combineLatest(
requests.map(req => req.pipe(tap(res => handleResponse(res))))
).subscribe();
const handleResponse = (response) => { /*do something*/ }
这是一个有效的 stackblitz 项目:https://stackblitz.com/edit/rxjs-a16kbu
我从@Harun Yilmaz 那里得到了解决方案post,只是我在这里添加它以供其他人参考。
getDataFromApi(url) {
let httpOptions={};
let param=["CAL3","CAL2","CAL1"];//dynamic parameter(CAL1:8sec,CAL2:5s,CAL3:12s)
let httpArray=[];
for(let i=0;i<param.length;i++){
httpArray.push(this.http.post<any>(url + `/PostDataSet?Id=${param[i]}`, {}, httpOptions))
}
const handleResponse = (response) => {
//here i am getting each response in a first come first manner
console.log(response.Table[0].Output);
}
const combineResponse =combineLatest(
httpArray.map(req => req.pipe(tap(handleResponse)))
)
return combineResponse;
}
//output
CAL2
CAL1
CAL3