Angular12中如何使用RxJS获取Firestore集合内存储的downloadURL
问题解决方案
问题原因
你当前代码的核心问题是Array.map搭配async函数后返回的是Promise数组,RxJS的map操作符不会自动等待这些异步任务完成,因此你拿到的流发出的值是未resolve的Promise集合,无法直接在模板中渲染。
修复代码
首先导入需要的RxJS操作符:
import { from, forkJoin, switchMap } from 'rxjs';
修改后的业务逻辑代码:
const listCollection = collectionData(collection(this.firestore, 'lists'), {idField: 'id'}); this.lists = listCollection.pipe( take(1), switchMap(lists => { // 为每一条列表项创建获取封面图地址的异步任务 const processedListTasks = lists.map(list => { const imgRef = ref(this.storage, list.metaImage); // 将Promise转为Observable,处理完成后拼接coverImg字段 return from(getDownloadURL(imgRef)).pipe( map(coverImg => ({ ...list, coverImg })) ); }); // 等待所有异步任务完成后返回完整列表 return forkJoin(processedListTasks); }) );
模板使用
直接配合Angular的async管道即可正常渲染:
<ul *ngIf="lists | async as listData"> <li *ngFor="let item of listData"> <img [src]="item.coverImg" alt="{{ item.title }}"> <p>{{ item.description }}</p> </li> </ul>
可选优化
如果你的列表数据量较大,不想等待所有图片加载完成再渲染列表,可以单独封装一个纯管道来处理单条数据的图片地址获取,实现文本先渲染、图片逐个加载的效果,同时避免重复请求。
内容的提问来源于stack exchange,提问作者Brandon Pearson
相关产品推荐
相关产品推荐

