我有一个项目数组,我想在每个元素上进行HTTP调用,等待它完成,然后再进行一次调用,一次只能调用一个.
我试过了:
index(item) {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}
async processArray(array) {
const promises = array.map(item => this.index(item));
await Promise.all(promises);
}
proccessArray(array);
还有NGRX效果:
@Effect()
effect$= this.actions$.pipe(
ofType<action>(actionTypes.action),
mergeMapTo(this.store.select(getMyArray)),
flatMap((request: any[]) => {
return zip(...request.map(item => {
return this.service.index(item).pipe(
map(response => {
// handle success case
}),
catchError(error => {
// handle error case
})
)
}))
}),
);
还尝试在for和forEach循环中执行它,但它们立即触发所有请求.我怎么能实现这个目标?
解决方法:
如果您正在使用承诺并希望等待每个承诺在另一个呼叫之前解决,那么(1)您不应该使用Promise.all,因为这将等待直到所有请求都被解决并且(2)您需要使用普通旧的 – 循环使您可以等待循环内的异步操作.
async processArray(array) {
for(var i = 0; i < array.length; i++){
await yourServiceCall();
}
}
作为旁注:由于您使用的是async-await,因此请不要忘记convert您的observables承诺.
如果你想远离promises(和async-await)并依赖纯粹的RxJS,请看看concatMap:
Projects each source value to an Observable which is merged in the output Observable, in a serialized fashion waiting for each one to complete before merging the next.
例如:
import { from } from 'rxjs/observable/from';
ngOnInit() {
from(myArray)
.pipe(concatMap(el => yourServiceCall(el)))
.subscribe(/* your logic */);
}