ngFor 中嵌套异步的最佳实践?

Posted

技术标签:

【中文标题】ngFor 中嵌套异步的最佳实践?【英文标题】:Best practices for nested async inside of ngFor? 【发布时间】:2021-11-15 10:51:12 【问题描述】:

假设我有一个汽车清单:

const cars: Array<carId: number> = [carId: 1, carId: 2];

然后我在模板中渲染它们:

<div *ngFor=“let car of cars”></div>

在该模板内部,我想从返回可观察对象的方法中获取一些动态图像路径:

<div *ngFor=“let car of cars”>
    <img [src]=“getImagePath(car) | async”>
</div>

getImagePath(car: carId: number): Observable<string> 
   return //some service request that brings back a url based on the carId

对于状态管理和存储,我使用的是 Firebase。我的所有图片都存储在一个存储桶中,我可以通过为我的服务提供一个 carId 来获取它们,该 carId 使用它来获取下载 URL。

我想避免在第一次保存文件时使用 downloadURL 更新 Firestore,因为我会将它们存储在子集合中,并且由于 Firestore 的性质,将它们从那里拉出来已经很痛苦了。

有没有办法更有效地做到这一点?如果列表开始增长,上面的代码肯定会让浏览器爬起来……对吧?

【问题讨论】:

也许我不明白;但是你为什么认为浏览器会爬起来呢?显然,如果你有大量的汽车列表,你会得到很多divs;然后您将下载许多图像......但这就是您正在构建的页面的性质(如果您不分页) - 不是 Angular 代码的低效率。另外,我不明白 Firestore 与您的问题有何关联 不是吗?如果我有一百辆车怎么办? DOM 渲染时不是有一百个活动订阅吗?我只提到 Firebase 是为了避免建议存储图像路径并将它们包含在汽车对象中的响应。 【参考方案1】:

您可以将其变成一个可观察对象并订阅一次,然后将返回的数组显示到您的 html 中,而不是直接在每个 img 元素上调用请求。

我使用了几个 RXJS 运算符来得到你想要的。

mergeMap 扁平化内部 observable ofcars 数组转换为 observable mapcars 数组转换为具有相应汽车图像路径的新数组 forkJoin - 我们将多个请求封装到一个 observable 中,并且只有在收到所有请求的响应时才会返回。

这当然只是一种方法,可能还有其他更好的方法。

getCarImages() 
  const cars: Array < 
    carId: number;
   > = [
      carId: 1,
    ,
    
      carId: 2,
    ,
  ]; 
  of(cars)
  .pipe(
      mergeMap((e) => 
        return forkJoin(
          e.map((item) => this.apiService.getCarImages(item.carId))
        ).pipe(
          map((paths) => 
            console.log(paths);
            return e.map((car, index) => (
              ...car,
              imagePath: paths[index],
            ));
          )
        );
      )
    )
    .subscribe((res) => 
      this.cars = res;
      console.log(this.cars);
    );

HTML:

<div *ngFor="let car of cars">
  <img [src]="car?.imagePath" />
</div>

我创建了一个stackblitz 来模拟解决方案。

【讨论】:

@katysha - 我认为你的方法更简单更好

以上是关于ngFor 中嵌套异步的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

Rails 4 [最佳实践] 嵌套资源和浅层:true

在 redux 中处理异步操作错误的最佳实践是啥?

Rails 中嵌套资源视图的最佳实践?

Swift NSFetchedResultsController 嵌套对象的最佳实践

构建异步邮件的最佳实践(使用 Sidekiq)

服务之间异步通信的最佳实践