#angular #ngfor #subscription
#angular #ngfor #подписка
Вопрос:
Я использую Angular 9. Я хочу загрузить серию объектов, каждый из которых содержит данные изображения. Сначала я хотел бы загрузить все объекты, а затем загрузить данные изображения. У меня есть это в моем файле component.ts ngOnInit …
ngOnInit(): void {
this.authService.getAllinLibrary().subscribe((res: any[]) => {
this.results = res;
...
for (let i = 0; i < results.length; i ) {
this.getTheImage(res[i].Id, i);
}
});
getTheImage(imageId: number, index: number) {
this.authService.getPersonImage(imageId).subscribe(data => {
this.createImageFromBlob(data, index);
this.isImageLoadingArr[index] = false;
console.log("loaded image:" index);
}, error => {
this.isImageLoadingArr[index] = false;
console.log(error);
});
}
Я отображаю данные в своем компоненте следующим образом
<mat-grid-tile *ngFor="let person of results; let i = index;" class="animated flipInX">
<div class="image-background">
<img [src]="images[i]"
alt="" width="100%">
Кажется, что все вызовы для загрузки данных изображения не выполняются одновременно. То есть каждый раз я получаю сообщения журнала
loaded image: 0
loaded image: 1
loaded image: 2
loaded image: 3
loaded image: 4
....
печатается в последовательном порядке, что наводит меня на мысль, что вызовы не выполняются одновременно. Как мне изменить то, что у меня есть, чтобы вызовы для получения источников изображений выполнялись одновременно, а не по одному за раз?
Комментарии:
1.Ну, из-за вашего цикла foreach вы будете вызывать запрос несколько раз. Дело не в том, что каждый запрос ожидает друг друга, но цикл foreach приводит к крошечной разнице. Если вы хотите вызвать несколько запросов, есть что-то вроде
Promise.all
или вrxjs
forkJoin()
. Взгляните на этот блог: coryrylan.com/blog/angular-multiple-http-requests-with-rxjs
Ответ №1:
Я думаю, что лучшая оценка — реализовать спецификации forkJoin Rxjs :
this.authService.getAllinLibrary().subscribe((res: any[]) => {
this.results = res;
...
let observableBatch = [];
results .forEach(( componentarray, key ) => {
observableBatch.push( this.getTheImage(res[key ].Id, key); );
});
const getImagesObservable= forkJoin(observableBatch );
getImagesObservable.subscribe({
next: value => your Implementation Here
complete: () => console.log('This is how it ends!'),
});
});
Комментарии:
1. Продолжение — здесь вы создаете массив, используя жестко запрограммированный «this.getTheImage(res[i] . Идентификатор, i) «. Если я не знаю, сколько экземпляров у меня есть во время компиляции, могу ли я сначала просто создать массив, а затем передать его в «const getImagesObservable= forkJoin(«?
2. Привет, я только что отредактировал свой ответ, вы можете использовать переменный observable patch для настройки ваших вызовов subscriptions и передать его в качестве аргумента операции fork-join , пожалуйста, поддержите, если это вам поможет 🙂
3. Спасибо! Последний вопрос — вы подписываетесь на forkJoin, а затем обрабатываете значения «next» и «complete». Я замечаю другие сайты, когда есть только «результаты», обработанные методом «subscribe». Есть ли какая-либо практическая разница между ними?