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

时间:2018-12-25 13:55:43

标签: 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);

还具有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
               })
            )
         }))
      }),
   );

也尝试在forforEach循环中执行此操作,但是它们会立即触发所有请求。我该如何实现?

1 个答案:

答案 0 :(得分:2)

如果您正在使用promise并且要等待每个promise的解决之后再进行另一个呼叫,则(1)您不应使用Promise.all,因为这将等待所有请求都被解决,并且(2)您需要使用普通的for循环,使您可以等待循环内的异步操作。

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Message.class, new MessageDeserializer());
mapper.registerModule(module);

Message readValue = mapper.readValue(json, Message.class);

作为旁注:由于您使用的是异步等待,所以请不要忘记convert遵守诺言。

如果您想摆脱承诺(和异步等待),转而依靠纯RxJS,请查看concatMap

  

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

例如:

async processArray(array) {
  for(var i = 0; i < array.length; i++){
    await yourServiceCall();
  }
}