Дождитесь окончания наблюдаемого цикла for, прежде чем продолжить цикл в Angular 5
Я перебираю массив объектов (называемых проектами). Цикл forEach содержит сервисный вызов, который возвращает наблюдаемое. Я пытаюсь дождаться обработки следующего проекта в массиве, пока не завершится наблюдаемое в цикле. Что я должен использовать? Я уже пробовал 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);
});
})
2 ответа
В конце концов я нашел решение. Ключ должен использовать вторую функцию, которая вызывается рекурсивно.
Передайте все проекты и индекс первого проекта 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);
});
}
Если вы хотите запустить один Observable одновременно и запускать следующий только после завершения предыдущего, то forkJoin
не является хорошим выбором, потому что он подписывается на все исходные Observables сразу. Лучшим подходом является использование так называемых наблюдаемых высшего порядка и подписка друг за другом с помощью 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);
Это моделирует HTTP-вызов, делая Observable с задержкой в 1 с. Если вы запустите этот пример, вы увидите, что он печатает каждое число с задержкой 1 с:
Посмотреть живую демонстрацию: http://jsbin.com/zocuma/3/edit?js,console