如何在循环内进行 HTTP 调用并等待一个完成后再进行另一个?

Ahm*_*mer 7 javascript rxjs ngrx

我有一组项目,我想在每个元素上进行 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);
Run Code Online (Sandbox Code Playgroud)

还有 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
               })
            )
         }))
      }),
   );
Run Code Online (Sandbox Code Playgroud)

也试着做它forforEach循环,但他们开火,一旦所有的请求。我怎么能做到这一点?

B12*_*ter 5

如果您正在使用 Promise 并希望在进行另一个调用之前等待每个 Promise 解决,那么(1)您不应该使用Promise.all,因为这将等到所有请求都得到解决并且(2)您需要使用普通的旧版本for-loop 使您能够在循环内等待异步操作。

async processArray(array) {
  for(var i = 0; i < array.length; i++){
    await yourServiceCall();
  }
}
Run Code Online (Sandbox Code Playgroud)

作为旁注:由于您使用的是 async-await,所以不要忘记将您的可观察量转换为承诺。

如果您想摆脱 Promise(和 async-await)并依赖纯 RxJS,请查看concatMap

将每个源值投影到一个 Observable,该 Observable 会合并到输出 Observable 中,以序列化方式等待每个源值完成,然后再合并下一个。

例如:

import { from } from 'rxjs/observable/from';

ngOnInit() {
  from(myArray)
    .pipe(concatMap(el => yourServiceCall(el)))
    .subscribe(/* your logic */);
}
Run Code Online (Sandbox Code Playgroud)

  • `concatMap` 运算符解决了这个问题。仅当前一个可观察对象完成时,它才会订阅下一个可观察对象。谢谢! (3认同)