Observable.forkJoin带有for循环

时间:2017-02-20 00:04:09

标签: javascript angular observable angular2-observables

我正在尝试填充名为processes的组件中的数组,该数组是process的数组。每个process也有一个tasks列表。

目前,我正在使用两个api调用:

/processes/process/{processId}/tasks

我使用/processes获取所有进程并最初填充processes数组。然后我使用每个process的进程ID来调用第二个API来获取该进程的任务。

目前,我的代码看起来像这样:

this.processes.forEach((process, index) => {
    myService.getTasks().subscribe((tasks) => {
        process.tasks = tasks;
    })
})

我知道我可以创建一个observable数组,并使用Observable.forkJoin()等待所有这些异步调用完成但我希望能够为每个调用定义subscribe回调函数,因为我需要对process的引用。关于我如何处理这个问题的任何想法?

2 个答案:

答案 0 :(得分:5)

使用for循环来发出多个HTTP请求,然后单独订阅所有这些请求,以避免打开很多Observable个连接。

正如@Juan Mendes所提到的,Observable.forkJoin将返回一系列与进程数组中每个进程的索引相匹配的任务。您还可以按照以下步骤为每个流程分配任务:

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]);
    }
);

还请看一下这篇文章:Send multiple asynchronous HTTP GET requests

答案 1 :(得分:0)

感谢Seid Mehmedovic的出色解释,但看起来代码似乎在地图附近丢失了一个圆括号。对我来说,它的工作方式如下:

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]);
    }
);