我循环遍历一个对象数组(称为项目)。 forEach循环包含一个返回observable的服务调用。我试图等待处理数组中的下一个项目,直到循环中的observable完成。我该怎么用?我已经尝试过forkJoin。
projects
.forEach(project => {
this.imageService.getProjectImages(project.projectId.toString(), true, true, undefined)
.catch(err => observer.error(err))
.finally(() => {
// process next project
})
.subscribe((image: FileRepresentation) => {
data.image = image;
this.getSlide(project, data);
});
})
答案 0 :(得分:1)
If you want to run one Observable at the time and only start the next one after the previous one completed then forkJoin
is not a good choice because it subscribes to all source Observables right away. A better approach is using so called higher-order Observable and subscribe to one after another with concatAll
:
const projects = [
Observable.of(1).delay(1000),
Observable.of(2).delay(1000),
Observable.of(3).delay(1000),
];
Observable.from(projects)
.concatAll()
.subscribe(console.log);
This simulates the HTTP call by making an Observable with 1s delay. If you run this example you'll see that it prints each number with 1s delay:
See live demo: http://jsbin.com/zocuma/3/edit?js,console
答案 1 :(得分:0)
我最终想出了一个解决方案。关键是使用递归调用的第二个函数。
将所有项目和第一个项目的索引传递给getImagesForProject。一旦收到第一个项目的所有图像,检查imageCount是否小于maxImages。如果是,则递归调用getImagesForProject,直到达到限制。
this.getImagesForProject(projects, 0, 5);
getImagesForProject(projects: Project[], index: number, maxImages: number = 5, imageCount?: number) {
this.imageService.getProjectImages(projects[index].projectId.toString(), true, true, undefined)
.finally(() => {
if(imageCount < maxImages) {
this.getImagesForProject(projects, data, (index + 1), imageCount);
}
})
.subscribe(image => {
imageCount++;
data.image = image;
this.getSlide(projects[index], data);
});
}