How to execute and get result of sequential HTTP calls using RxJS

筅森魡賤 提交于 2021-02-08 10:12:44

问题


I want to make several HTTP calls sequentially and after each call, I want to examine the result and make another call and display message, etc. In some cases continue to the next call, some cases break on that call after displaying message. On the other hand, I also need to use catchError block of each call (or maybe a single block for all of them, but using one for each call would be better).

So, assume that I have an create, update and delete calls as shown below. How can I get each of these call's response and check the response and then execute another call?

I have tried switchMap and iif and I am looking a solution using one of them. Any suggestion?

this.service.create('/api/employee').subscribe(resp1 => {
    this.service.update('/api/salary/', id).subscribe(resp2 => {
        this.service.delete('/api/education/', id).subscribe(resp3 => {

        // I need to get response of each call from starting thr first and then continue of 
        // break according to the condition of the response

  });
});

回答1:


Using switchMap here is a good approach:

this.service.create('/api/employee')
 .pipe(switchMap((resp) => {
    if(fulfillsCondition(resp)) {
       return this.service.update(...);
    }
    return this.service.delete(...);
})).subscribe();



回答2:


I'm not sure there's much else to say here.

Of note, perhaps, is that EMPTY is an RxJs stream that emits nothing and completes immediately. It is sort of like "break" (in a pretty loose way. How you "break" from a stream can be pretty context dependant).

this.service.create('/api/employee').pipe(
  catchError(err1 => {
    // do some stuff
    return throwError(err1);
  }),
  switchMap(resp1 => {
    // do some stuffs
    if(someCondition(resp1)){ 
      return this.service.update('/api/salary/', id).pipe(
        catchError(err2 => {
          // do some stuff
          return throwError(err2);
        }),
      );
    }
    return EMPTY;
  }),
  switchMap(resp2 => {
    // do some stuff
    if(someCondition(resp2)){ 
      return this.service.delete('/api/education/', id).pipe(
        catchError(err3 => {
          // do some stuff
          return throwError(err3);
        }),
      );
    }
    return EMPTY;
  }),
).subscribe({
  next: resp3 => { /*do some stuff*/ },
  complete: () => { /*Your stream is done*/ },
  eror: err => { /*All re-thrown errors end up here */ }
});

Update

Using tap to help understand streams

tap is an operator that returns the same stream that it receives. It can't make any changes to your stream, but it can look at what is happening at any given point. This can be a useful tool to aid your understanding.

http1().pipe(
  tap({
    next: val => console.log("Result from http1 call: ", val),
    complete: () => console.log("http1 call completed"),
    error: err => console.log("http1 call errored: ", err)
  })
  switchMap(val => http2(val).pipe(
    tap({
      next: val => console.log("Result from http2 call: ", val),
      complete: () => console.log("http2 completed"),
      error: err => console.log("http2 call errored: ", err)
    })
  )),
  tap({
    next: val => console.log("Result from switchMap operator: ", val),
    complete: () => console.log("switchMap completed"),
    error: err => console.log("switchMap (http1 or http2 call) errored: ", err)
  })
).subscribe()

Here we can see what is happening before and after the switchMap. You can see that in this case, switchMap is taking a value from http1 and emitting the values from http2.

Because switchMap waits for values from http1 before generating http2, one side effect is that http2 doesn't start until after http1 emits. This does mean that these calls are executed sequentially, but the story gets more complicated if http1 emits more than once.

More About:

  • switchMap
  • concatMap
  • mergeMap


来源:https://stackoverflow.com/questions/64858071/how-to-execute-and-get-result-of-sequential-http-calls-using-rxjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!