【问题标题】:Observable.forkJoin with a for loopObservable.forkJoin 与 for 循环
【发布时间】:2017-07-09 03:16:40
【问题描述】:

我试图在我的组件中填充一个名为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() 等待所有这些异步调用完成,但我希望能够为每个调用定义订阅回调函数,因为我需要一个参考到process。关于如何解决这个问题的任何想法?

【问题讨论】:

  • Observable.forkJoin 将返回一个任务数组,该数组与您的进程数组中每个进程的索引相匹配

标签: javascript angular observable angular2-observables


【解决方案1】:

应避免使用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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 2015-08-28
      • 2011-07-12
      • 2012-11-04
      • 1970-01-01
      相关资源
      最近更新 更多