我有一个函数,它从一个项目数组(myItemsArray)创建一个Observables数组(batchOfRequests)。每个myItem使用myItem属性(propertyOne,propertyTwo等)中的两个参数推送一个Observable(http请求)然后使用Observable.concat在batchOfRequests中为每个Observable发出请求。这工作正常,我可以在returnedData中看到每个请求返回的数据。但是,此时,我不知道myItemsArray中的哪个myItem属于每个请求。有没有办法将每个myItem链接或映射到推入batchOfRequests的Observable?
performMultipleRequests(): void
{
let batchOfRequests: Observable<any>[] = [];
for (let myItem of this.myItemsArray)
{
this.batchOfTrendRequests.push(this.myService.makeHTTPCall(myItem.propertyOne, myItem.propertyTwo))
}
this.batchOfRequests = this.batchOfRequests.map(obs =>
{
return obs.catch(err => Observable.of(err));
});
Observable.concat(...this.batchOfRequests)
.finally(() =>
{
return;
})
.subscribe((returnedData: any) =>
{
// do something with my returned data... but I need myItem information as well
return;
}), (error) =>
{
return;
}
}
答案 0 :(得分:3)
forkJoin将以与myItemsArray相同的顺序发出一系列响应。因此,您可以根据其数组索引将每个响应匹配回其请求:
performMultipleRequests(): void {
let batchOfRequests: this.myItemsArray.map(myItem =>
this.myService.makeHTTPCall(myItem.propertyOne, myItem.propertyTwo)
.catch(err => Observable.of(err))
);
Observable.forkJoin(...batchOfRequests).subscribe((myResponsesArray: any[]) => {
myResponsesArray.forEach((returnedData, index) => {
// lookup myItem corresponding to this returnedData
const myItem = this.myItemsArray[index];
...
});
});
}
请注意,使用.catch()
可确保部分失败不会导致整批失败。
答案 1 :(得分:0)
您可以在推送到阵列之前映射所需的数据。像这样:
let batchOfRequests: Observable<{ myData: any, httpResponse: any }>[] = [];
for (let myItem of this.myItemsArray)
{
const httpRequest = this.myService.makeHTTPCall(myItem.propertyOne, myItem.propertyTwo);
const mappedRequest = httpRequest.map(res => {
return { myData: myItem, httpResponse: res };
});
batchOfRequests.push(mappedRequest);
}
而不是在填充数组后使用map,你也可以在循环中进行错误捕获:
let mappedRequest = httpRequest.map(res => {
return { myData: myItem, httpResponse: res };
});
mappedRequest = mappedRequest.catch(err => Observable.of(err));
答案 2 :(得分:0)
您可以使用async / wait,如下所示,
优点是
点击此处:JavaScript Demo: Promise.all()
async performMultipleRequests(): void
{
let batchOfRequests: Promise<any>[] = [];
for (let myItem of this.myItemsArray)
{
this.batchOfTrendRequests.push
(this.myService.makeHTTPCall
(myItem.propertyOne, myItem.propertyTwo).toPromise());
}
//this will return you array of all completed request
const allRetunValue = await Promise.all(batchOfTrendRequests);
allRetunValue.forEach(retval=> { console.log(retval); });
}