如何在 RxJS 中“等待”两个可观察对象

新手上路,请多包涵

在我的应用程序中,我有类似的东西:

 this._personService.getName(id)
      .concat(this._documentService.getDocument())
      .subscribe((response) => {
                  console.log(response)
                  this.showForm()
       });

 //Output:
 // [getnameResult]
 // [getDocumentResult]

 // I want:
 // [getnameResult][getDocumentResult]

然后我得到两个分开的结果,第一个是 _personService ,然后是 _documentService 。我如何才能在调用 this.showForm() 之前等待两个结果完成然后操作每个结果。

原文由 gog 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 796
2 个回答

最后更新:2022 年 3 月。

RxJS v7:结合最新与

来自 reactX 文档

每当任何输入 Observable 发出一个值时,它都会使用所有输入的最新值计算一个公式,然后发出该公式的输出。

 // Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

name$.pipe(
        combineLatestWith($document)
      )
      .subscribe(([name, document]) => {
           this.name = name;
           this.document = pair.document;
           this.showForm();
       })

(已弃用)RxJS v6 combineLatest()

来自 reactX 文档

每当任何输入 Observable 发出一个值时,它都会使用所有输入的最新值计算一个公式,然后发出该公式的输出。

(更新:2021 年 2 月)

 // Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

name$.combineLatest(document$, (name, document) => {name, document})
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })

(替代语法) : combineLatest(observables)

 // Deprecated (RxJS v6)
// Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

combineLatest(name$, document$, (name, document) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })


zip vs combine最新

(更新:2018 年 10 月) 我之前建议使用 zip 方法。但是,对于某些用例, combineLatestzip --- 有一些优势。因此了解差异很重要。

CombineLatest 从 observables 发出最新的发射值。而 zip 方法 按顺序 发出发出的项目。

例如,如果 observable #1 发出了它的 第 3 个 项目,而 observable #2 发出了它的 第 5 个 项目。使用 zip 方法的结果将是 observables第三个 发射值。

在这种情况下,使用 combineLatest 的结果将是第 5第 3 。感觉更自然。


Observable.zip(可观察)

(原始答案:2017 年 7 月) Observable.zip 方法在 reactiveX 文档 中有说明:

组合多个 Observable 以创建一个 Observable,其值是根据其每个输入 Observable 的值按顺序计算的。

 // Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

Observable
    .zip(name$, document$, (name: string, document: string) => ({name, document}))
    .subscribe(pair => {
           this.name = pair.name;
           this.document = pair.document;
           this.showForm();
       })


旁注(适用于两种方法)

我们提供函数的最后一个参数 (name: string, document: string) => ({name, document}) 是可选的。你可以跳过它,或者做更复杂的操作:

如果最新的参数是一个函数,则该函数用于根据输入值计算创建的值。否则,返回输入值数组。

所以如果你跳过最后一部分,你会得到一个数组:

 // Observables to combine
const name$ = this._personService.getName(id);
const document$ = this._documentService.getDocument();

Observable
    .zip(name$, document$)
    .subscribe(pair => {
           this.name = pair['0'];
           this.document = pair['1'];
           this.showForm();
       })

原文由 Hamid Asghari 发布,翻译遵循 CC BY-SA 4.0 许可协议

使用 forkJoin() 观察方法。 检查此链接以供参考

来自 RXJS 文档

当您有一组可观察对象并且只关心每个对象的最终发射值时,最好使用此运算符。一个常见的用例是,如果您希望在页面加载(或其他事件)时发出多个请求,并且只想在收到所有响应后才采取行动。通过这种方式,它类似于您可能使用 Promise.all 的方式

forkJoin([character, characterHomeworld]).subscribe(results => {
  // results[0] is our character
  // results[1] is our character homeworld
  results[0].homeworld = results[1];
  this.loadedCharacter = results[0];
});

代码取自: https ://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs

原文由 Prathmesh Dali 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题