简体   繁体   English

角度5-另一个观察者内部的观察者循环-做到这一点的有效方法

[英]angular 5 - loop of observers inside an other observer - efficient way to do it

I have a 'get' call that returns a list of users that contains a user id and a name. 我有一个“获取”调用,该调用返回包含用户ID和名称的用户列表。 After the call succeeded, I need to call another rest for each user to bring his picture. 通话成功后,我需要为每个用户打电话给其他人带来他的照片。

Currently I am doing this in this way- 目前,我正在以这种方式进行操作-

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] = '';
        }
      });
    });
  });
}

In my html- 在我的html-

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

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

Where display-picture is a component that just presents the image. 其中显示图片是仅显示图像的组件。

Is there any efficient way using rxjs to do it? 有没有使用rxjs的有效方法呢?

from to iterate each user and mergeScan can be used here to execute the observables. from开始迭代每个用户,并可以在此处使用mergeScan执行可观察对象。 For clarity i break it into two functions. 为了清楚起见,我将其分为两个功能。 You can also control the number of concurrency with mergeScan 您还可以使用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 https://stackblitz.com/edit/rxjs-1bt172

You can use a forkJoin() to merge together all the final emitted values from multiple observables. 您可以使用forkJoin()将来自多个可观察对象的所有最终发出的值合并在一起。 RxJS 6 supports using an object map of key/value pairs to define which observables, but you'll have to use an array for older versions. 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) : '';
   });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM