javascript - 等到所有 Observables 完成
问题描述
我的代码中很少有像这样的 Observable。
this.server.doRequest().subscribe(response => console.log(response)
error => console.log(error),
() => {
console.log('completed');
});
这些 Observable 可能有任意数量,因此我需要编写一个函数来检查每个 Observable 是否已完成,否则会等到每个 Observable 完成。
我假设我可以创建一个数组,在那里推送每个新的 Observable,并在完成后按索引将其删除。但这是好的解决方案吗?
我想在哪里使用它。例如,我有一个页面,用户在其中异步上传任意数量的照片,然后他按下完成按钮。一旦他按下完成按钮,我需要等到所有动态创建的 Observables 完成。
解决方案
您应该为此使用更高阶的可观察对象,您的确切用例将决定确切的运算符,但 forkJoin 似乎是一个不错的选择:
forkJoin(
this.server.doRequest1(),
this.server.doRequest2(),
this.server.doRequest3(),
this.server.doRequest4()
).subscribe(vals => console.log('all values', vals));
在所有内部可观察对象完成之前,forkJoin 不会发出。使其成为等待多个可观察对象完成的首选操作符。你也可以给它一个可观察的数组。还有多个其他运算符也可以满足您的情况,例如 concat、merge、combineLatest 或其他一些运算符。
根据更多细节进行编辑:
在更新中描述的用例中,您仍然希望使用更高阶的 observable,但 forkjoin 不是您想要的。您将希望使用本地主题来完成目标,因为希望在选择每个可观察对象时启动它并等待它们全部完成会使事情变得有点复杂(但不是太多):
假设你有一个像这样的模板:
<button (click)="addPhoto()">Add Photo</button>
<button (click)="finish()">Finish</button>
添加照片按钮获取用户照片和所有这些,完成是你的完成,你可以有一个这样的组件:
private addPhoto$ = new Subject();
constructor() {
this.addPhoto$.pipe(
mergeMap(() => this.uploadPhoto()),
).subscribe(
(resp) => console.log('resp', resp),
(err) => console.log('err', err),
() => console.log('complete')
);
}
private uploadPhoto() {
// stub to simulate upload
return timer(3000);
}
addPhoto() {
this.addPhoto$.next();
}
finish() {
this.addPhoto$.complete();
}
如果您运行此代码,您会看到添加的照片在完成时将在订阅处理程序中发出,但只有在所有照片上传完成并且用户单击完成后才会触发完成。
这是一个演示功能的stackblitz:
推荐阅读
- regex - 正则表达式:需要帮助在文件中查找匹配项
- php - 如何根据用户的访问方式更改我的页面以显示不同的信息?
- java - Java - 使用实例化反射防止字段分配?
- php - PHP Curl使用界面从视频页面获取视频源网址但不在html5视频播放器上播放
- api - Youtube API 频道搜索 - 如何使用视频 ID 获取频道 ID
- scala - 以下是否在火花中为每一行的每个执行程序创建一个新对象?
- python - Python - 将项目添加到文件右键单击上下文菜单
- node.js - 使用英特尔傲腾磁盘获取硬盘序列号
- mysql - 从一组条目中选择一个不同的行
- intellij-idea - IntelliJ Ktor 和 Docker 有没有更好的方法?