有很多类似性质的问题,我认为这有点不同。
考虑以下代码:
arr = [];
this.service1.getItem()
.subscribe(item => {
Object.entries(item).forEach(([key, value]) => {
if (some_condition_true) {
this.service2.getSomeItems2(value.prop1).pipe(first())
.subscribe(result => value.xyz = result);
this.arr.push(value);
}
});
});
// This line should execute only after the 'forEach' above completes
this.someService.someMethod(arr);
问题是我不知道将service2.getSomeItems2
呼叫多少次。
此外,zip
和forkJoin
占用Observables
,但我已经订阅了。也许我可以tap
代替subscribe
。但是事实仍然是未知数。
答案 0 :(得分:0)
怎么样?
this.service1.getItem()
.pipe(switchMap(items => {
const itemReqs = Object.entries(items)
.filter(v => some_condition_true_or_false)
.map(item => this.service2.getSomeItems2(item.prop1).pipe(first()));
return forkJoin(itemReqs);
}))
.subscribe(data_from_service_2_calls => {
data_from_service_2_calls.forEach(v => console.log(v))
});
可能存在语法错误,但是我认为这是您想要的。请记住,您应该避免在内部订阅。
希望有帮助!
答案 1 :(得分:0)
如果可能的话,您应该订阅而不是提早订阅,并将您的逻辑转移到Observables的pipe
中。
这里的技巧是将第一个请求(使用mergeMap
或switchMap
)映射到多个第二个请求的联合输出(使用forkJoin
)。
我认为它应该像这样:
this.service1.getItem()
.pipe(
mergeMap(item => forkJoin(getItemRequests(item)))
).subscribe(arr => this.someService.someMethod(arr));
getItemRequests(item: any): Observable<any>[] {
return Object.entries(item)
.filter(([key, value]) => some_condition_true)
.map(([key, value]) => this.service2.getSomeItems2(value.prop1)
.pipe(
first(),
tap(result => value.xyz = result),
map(result => value)
)
);
}