【问题标题】:Chaining dependent Observables in RxJs在 RxJs 中链接依赖的 Observable
【发布时间】:2019-06-14 08:19:54
【问题描述】:

链接一系列 HttpClient 调用的“最佳实践”是什么(假设当前调用取决于先前调用的结果)?以下解决方案是有效的,但显然不推荐。每个 get 返回一个 Observable。在解决方案中首选使用“管道”运算符(RxJs 中的较新方法)。

ngOnInit() {
  this.firstService.get().subscribe((first) => {
    this.secondService.get().subscribe(second => {
      this.thirdService.get().subscribe(third => {
        ... possibly more nested calls ...
      })
    })
  })
}

【问题讨论】:

标签: angular rxjs angular-httpclient


【解决方案1】:

您的代码远远超出了最佳实践。永远不要在另一个内部订阅。

如果你的任务是三个独立的tasks/observables,彼此不依赖,那么考虑使用forkJoin(所有的Observables同时开始,最后一个observables结束时返回结果)

let observable1(param1);
let observable2(param2);
let observable3(param3);

let joinedObservables = forkJoin(observable1, observable2, observable3).subscribe(x => {
  let result1 = x[0];
  let result2 = x[1];
  let result3 = x[2];

  ...
});

如果它们的结果相互依赖,您可以使用switchMapflatMapmergeMapexhaustMap(检查差异)

let resultObservable =  return this.observable1().pipe(mergeMap((param1) => {
  return this.observable2().pipe(map((param1) => {

    ....        

    return <result>;
  }));
}));

resultObservable.subscribe(x => {
   ...
});

【讨论】:

  • 是的。我认为这是一种不好的做法,但我想将其展示为基于 Promise 或链式回调的传统代码的典型天真转换,这使得与适当解决方案的对比变得清晰。
  • 如果您认为此答案有帮助,请考虑将其标记为 amswer,以便社区可以从中受益
  • 撞了它。谢谢。
【解决方案2】:

如果您需要嵌套调用的原因是使用来自先前调用的数据,我建议使用带有 mergeMaps 和更多管道/映射的管道运算符来返回下一个调用来代替先前的调用。

应该类似于(省略订阅和取消订阅):

this.firstService.pipe(
    mergeMap(res =>
        this.secondService.get().pipe(
            map(data => data),
        ),
    ... <more as needed>
);

如果它们不需要嵌套,在 promiseAll 中使用this.service.get().toPromise() 会更容易。

【讨论】:

  • 我看不出使用 Promises 的任何优势,它是 Observable 的旧版本(发出一次),即使在进行 HTTP 调用(接收后完成)时,使用 Observable 和关联运算符。
  • 是什么让 promise 成为 observable 的旧版本?带有 Promise 的异步/等待编程风格都是非常新的并且被广泛使用。 Angular 经常将两者用于不同的目的。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 表明他们的效用最近在扩大。这只是另一种观点和另一种用于完成类似工作的工具。这里的重点是一次性(承诺)与流(可观察)。
猜你喜欢
  • 2021-09-13
  • 2021-01-16
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2020-03-28
  • 1970-01-01
  • 1970-01-01
  • 2021-01-01
相关资源
最近更新 更多