代码之家  ›  专栏  ›  技术社区  ›  chris01

RxJS:HTTP请求的顺序

  •  0
  • chris01  · 技术社区  · 3 年前

    我有多个休息要求要做。请求应该按照声明的顺序发生——一个接一个地发生。

    在所有这些结束时,我需要做一个动作。

    我怎么能得到呢?我认为一定有比级联请求更好的方法。 但我在RxJS和异步编程方面非常差。

    this.http.get <any> ("/a").subscribe ((resp) => { foo ();  
         this.http.get <any> ("/b").subscribe ((resp) => { bar ();
              this.http.get <any> ("/c").subscribe ((resp) => { baz (); }}}
    );
    
    // action now
    
    0 回复  |  直到 3 年前
        1
  •  2
  •   Picci    3 年前

    在这种情况下,我会使用 concatMap .

    代码应该是这样的

    this.http.get <any> ("/a").pipe(
      concatMap(respA => {
        foo();
        return this.http.get <any> ("/b");
      }),
      concatMap(respB => {
        bar();
        return this.http.get <any> ("/c");
      })
    ).subscribe(
      respC => { 
        baz(); 
      }
    );
    

    海图 确保按顺序执行调用。

    您可能会在如何在频繁的http相关用例中使用rxJs上找到灵感 in this article.

        2
  •  1
  •   Lukasz Gawrys    3 年前

    使用 forkJoin 为了这个

    import { forkJoin } from 'rxjs';

    像这样使用它

    forkJoin([this.http.get("/a"), this.http.get("/b"), this.http.get("/c")]).subscribe(([respA, respB, respC]) => {});
    

    forkJoin函数的输入必须是一个可观察的数组。

    编辑:

    在阅读了@Picci的fair point之后,我建议使用 concat 操作人员您可以将副作用放入每个可观察对象的tap运算符中,并将一组可观察对象传递给concat,concat将保持顺序。

    const a$ = this.http.get("/a").pipe(tap(() => foo()));
    const b$ = this.http.get("/b").pipe(tap(() => bar()));
    const c$ = this.http.get("/c").pipe(tap(() => baz()));
    
    concat([a$, b$, c$]).subscribe(([respA, respB, respC]) => {});
    
    // if you want to handle http errors, you can do it like this
    
    const a$ = this.http.get("/a").pipe(
      tap(() => foo()),
      catchError((err) => {
        handleErr(err);
        return of(EMPTY);
      })
    );