[英]Observable.forkJoin with a for loop
I am trying to populate an array in my component called processes
which is an array of process
. 我正在尝试在我的组件中填充一个名为
processes
的数组,这是一个process
数组。 Each process
also has a list of tasks
. 每个
process
还有一个tasks
列表。
So currently, I am working with two api calls which are: 所以目前,我正在使用两个api调用:
/processes
and /process/{processId}/tasks
/processes
和/process/{processId}/tasks
I use /processes
to get all the processes and initially populate the processes
array. 我使用
/processes
来获取所有进程并最初填充processes
数组。 Then I use the process id of each process
to call the second API to get the tasks of that process. 然后我使用每个
process
的进程ID来调用第二个API来获取该进程的任务。
Currently, my code looks something like this: 目前,我的代码看起来像这样:
this.processes.forEach((process, index) => {
myService.getTasks().subscribe((tasks) => {
process.tasks = tasks;
})
})
I understand that I can create an array of observables, and use Observable.forkJoin()
to wait for all these async calls to finish but I want to be able to define the subscribe callback function for each of the calls since I need a reference to the process
. 我知道我可以创建一个observable数组,并使用
Observable.forkJoin()
等待所有这些异步调用完成但我希望能够为每个调用定义subscribe回调函数,因为我需要一个引用这个process
。 Any ideas on how I can go about approaching this issue? 关于如何处理这个问题的任何想法?
Using the for
loop to make multiple HTTP requests, and then subscribe to all of them separately should be avoided in order not to have many Observable
connections opened. 使用
for
循环来发出多个HTTP请求,然后分别订阅所有这些请求,以避免打开很多Observable
连接。
As @Juan Mendes mentioned, Observable.forkJoin
will return an array of tasks that match the index of each process in your processes array. 正如@Juan Mendes所提到的,
Observable.forkJoin
将返回一个与进程数组中每个进程的索引相匹配的任务数组。 You can also assign tasks to each process as they arrive as follows: 您还可以在到达时为每个流程分配任务,如下所示:
getTasksForEachProcess(): Observable<any> {
let tasksObservables = this.processes.map(process, processIdx) => {
return myService.getTasks(process)
.map(tasks => {
this.processes[processIdx].tasks = tasks; // assign tasks to each process as they arrive
return tasks;
})
.catch((error: any) => {
console.error('Error loading tasks for process: ' + process, 'Error: ', error);
return Observable.of(null); // In case error occurs, we need to return Observable, so the stream can continue
});
});
return Observable.forkJoin(tasksObservables);
};
this.getTasksForEachProcess().subscribe(
tasksArray => {
console.log(tasksArray); // [[Task], [Task], [Task]];
// In case error occurred e.g. for the process at position 1,
// Output will be: [[Task], null, [Task]];
// If you want to assign tasks to each process after all calls are finished:
tasksArray.forEach((tasks, i) => this.processes[i].tasks = tasksArray[i]);
}
);
Please also take a look at this post: Send multiple asynchronous HTTP GET requests 另请看这篇文章: 发送多个异步HTTP GET请求
Thanks to Seid Mehmedovic for great explanation but it looks like code missing one round bracket near map. 感谢Seid Mehmedovic提供了很好的解释,但看起来代码在地图附近丢失了一个圆括号。 For me it worked as follows:
对我来说它的工作原理如下:
getTasksForEachProcess(): Observable<any> {
let tasksObservables = this.processes.map((process, processIdx) => {
return myService.getTasks(process)
.map(tasks => {
this.processes[processIdx].tasks = tasks; // assign tasks to each process as they arrive
return tasks;
})
.catch((error: any) => {
console.error('Error loading tasks for process: ' + process, 'Error: ', error);
return Observable.of(null); // In case error occurs, we need to return Observable, so the stream can continue
});
});
return Observable.forkJoin(tasksObservables);
};
this.getTasksForEachProcess().subscribe(
tasksArray => {
console.log(tasksArray); // [[Task], [Task], [Task]];
// In case error occurred e.g. for the process at position 1,
// Output will be: [[Task], null, [Task]];
// If you want to assign tasks to each process after all calls are finished:
tasksArray.forEach((tasks, i) => this.processes[i].tasks = tasksArray[i]);
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.