这是我的代码,我从一个空数组开始,想要调用一个对填充数组进行一些操作的服务。我使用两次对服务的调用来填充数组,这些服务调用 API 来接收要插入到数组中的元素。
我不知道如何让最后一个服务调用等到数组被填充后再执行。我认为我有两个单独的服务调用需要等待,而且它们都有 forEach 循环,这使得这比原本可能的更困难。有任何想法吗?
const subscribers: ISubscriber[] = [];
this.selectedChildren.forEach(child => {
this.serviceA.getSubscribers(child.id).subscribe( (subs: ISubscriber[]) => {
subs.forEach(s => {
subscribers.push(s);
});
});
});
this.selectedSubscribers.forEach(sub => {
this.serviceB.getSubscriber(sub.subscriberId).subscribe( (sub: ISubscriber) => {
subscribers.push(sub);
});
});
// subscribers is always empty when this call is made
// since above code hasn't finished executing
this.serviceC.processSubscribers(subscribers).subscribe( sub => {
this.toastr.success('Success!');
});
异步/等待尝试不起作用:
async doSomething(){
const subscribers: ISubscriber[] = [];
await this.selectedChildren.forEach(async child => {
await this.serviceA.getSubscribers(child.id).subscribe( (subs: ISubscriber[]) => {
subs.forEach(s => {
subscribers.push(s);
});
});
});
await this.selectedSubscribers.forEach(async sub => {
await this.serviceB.getSubscriber(sub.subscriberId).subscribe( (sub: ISubscriber) => {
subscribers.push(sub);
});
});
// subscribers is always empty when this call is made
// since above code hasn't finished executing
this.serviceC.processSubscribers(this.id, subscribers).subscribe( id => {
this.toastr.success('Success!');
});
}
Promise.all 尝试不起作用:
doSomething(){
const subscribers: ISubscriber[] = [];
const promises = [];
this.selectedChildren.forEach(child => {
promises.push(this.serviceA.getSubscribers(child.id).subscribe( (subs: ISubscriber[]) => {
subs.forEach(s => {
subscribers.push(s);
});
}));
});
this.selectedSubscribers.forEach(sub => {
promises.push(this.serviceB.getSubscriber(sub.subscriberId).subscribe( (sub: ISubscriber) => {
subscribers.push(sub);
}));
});
// subscribers is always empty when this call is made
// since above code hasn't finished executing
Promise.all(promises).then( a => {
this.serviceC.processSubscribers(this.id, subscribers).subscribe( id => {
this.toastr.success('Success!');
});
});
}
最佳答案
使用 rxjs 运算符的解决方案:
- 请记住,您在可观察链中应该只有1 个订阅
- combineLatest 相当于 Promise.all
- switchmap允许您将serviceA和serviceB的结果类型更改为serviceC
const subscribers: ISubscriber[] = [];
const subscriberObservables = [];
// First you add all async calls into an array
this.selectedChildren.forEach(child => {
subscriberObservables.push(this.serviceA.getSubscribers(child.id));
});
this.selectedSubscribers.forEach(sub => {
subscriberObservables.push(this.serviceB.getSubscriber(sub.subscriberId));
});
// then you run all of them in parallel
combineLatest(subscriberObservables)
.pipe(
map((arrayOfArrays:ISubscriber[][]) => arrayOfArrays.flat()),
switchMap( (subs: ISubscriber[]) => this.serviceC.processSubscribers(subscribers))
)
.subscribe( sub => {
this.toastr.success('Success!');
});
关于angular - 在以 Angular 调用之前等待数组完成填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55284655/