угловой 5 - петля наблюдателей внутри другого наблюдателя - эффективный способ сделать это - PullRequest
0 голосов
/ 09 июля 2019

У меня есть вызов get, который возвращает список пользователей, который содержит идентификатор пользователя и имя.После успешного вызова мне нужно вызвать еще одного отдыха для каждого пользователя, чтобы принести его фотографию.

В настоящее время я делаю это следующим образом -

component-

users;
userPhotos = {};

constructor(private dashboardService: DashboardService) {
  this.dashboardService.bringUsers().subscribe((data) =>{
    this.users = data;
    this.users.forEach((user) => {
      this.dashboardService.getPicture(user.userID).subscribe((data) => {
        if (data){
          this.userPhotos[user.userID] = window.URL.createObjectURL(data);
        } else {
          this.userPhotos[user.userID] = '';
        }
      });
    });
  });
}

В моем html-

<ng-container *ngFor="let user of users">
  <div>
      {{user.displayName}}
  </div>

  <display-picture [image]="userPhotos[user.userID]"></display-picture>
</ng-container>

Где display-picture - это компонент, который просто представляет изображение.

Есть ли эффективный способ использовать rxjs для этого?

Ответы [ 2 ]

4 голосов
/ 09 июля 2019

from для итерации каждого пользователя и mergeScan можно использовать здесь для выполнения наблюдаемых.Для ясности я разбил его на две функции.Вы также можете контролировать количество параллелизма с помощью mergeScan

    const getUserPic=users=>from(users).pipe(
        mergeScan((acc, curr:any) =>
            getPicture(curr.userID).pipe(map(photo => {
                acc[curr.userID] = photo
                return acc
            }))
          ,{})
        ) 

bringUsers().pipe(
    tap(users=>this.users=users),
    switchMap(users=> getUserPic(users)),
    last()
).subscribe(console.log)

https://stackblitz.com/edit/rxjs-1bt172

1 голос
/ 09 июля 2019

Вы можете использовать forkJoin () , чтобы объединить все окончательные значения из нескольких наблюдаемых.RxJS 6 поддерживает использование карты объектов из пар ключ / значение, чтобы определить, какие наблюдаемые, но вам придется использовать массив для более старых версий.

this.dashboardService.bringUsers().pipe(
   switchMap(users => forkJoin(
       users.reduce((acc, user) => (acc[user.userId] = this.dashboardService.getPicture(user.userID), acc), {}
   ))),
).subscribe((users: {[userId: number]: any}) => {
   Object.entries(users).forEach(([userId, data]:[number,any]) => {
      this.userPhotos[user.userID] = data ? window.URL.createObjectURL(data) : '';
   });
});
...