【问题标题】:RxJS: Order of HTTP-requestsRxJS:HTTP 请求的顺序
【发布时间】:2021-02-21 20:25:22
【问题描述】:

我有多个 REST 请求要做。请求应该按照声明的顺序发生 - 一个在另一个结束之后。

最后我需要做一个动作。

我怎样才能得到它?我认为必须有比级联请求更好的方法。 但我在 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

【问题讨论】:

标签: angular rxjs


【解决方案1】:

在这种情况下我会使用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(); 
  }
);

concatMap 确保调用按顺序执行。

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

【讨论】:

    【解决方案2】:

    为此使用forkJoin

    import { forkJoin } from 'rxjs';

    并像这样使用它

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

    forkJoin 函数的输入必须是一个 observables 数组。

    编辑:

    从@Picci 阅读公平点后,我建议使用concat 运算符。您可以将副作用放入每个 observable 的 tap 运算符中,并且仍然将一组 observables 传递给 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);
      })
    );
    

    【讨论】:

    • forkJoin 并行执行所有调用,不保证顺序。 concatMap 是我建议的运营商。
    • 当请求出现问题时停止(例如 HTTP 404)。我怎样才能让它继续下去?
    • 我用一个例子扩展了答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 2017-10-07
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多