您应该为此使用更高阶的 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();
}
如果您运行此代码,您会看到添加的照片在完成时将在订阅处理程序中发出,但只有在所有照片上传完成并且用户单击完成后才会触发完成。
这是一个演示功能的堆栈闪电战:
https://stackblitz.com/edit/angular-bsn6pz