如何在 RxJS 中“等待”两个可观察量zip vs combine最新可观察.zip(可观察量)

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

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

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

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

然后我得到两个单独的结果,首先是.我怎么能等到两个结果之前调用完成一个然后操纵每个结果。_personService_documentServicethis.showForm()


答案 1

上次更新时间:2022 年 3 月。

RxJS v7: 结合最新与

来自 reactiveX 文档

每当任何输入 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()

来自 reactiveX 文档

每当任何输入 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 月)我之前建议使用方法。但是,对于某些用例,与 相比,具有一些优势。因此,了解差异非常重要。zipcombineLatestzip

CombineLatest从可观察量发出最新发出的值。While 方法按顺序发出发出的项。zip

例如,如果可观察 #1 发出其第 3 项,而可观察 #2 已发出其第 5 项。使用方法的结果将是两者的第三个发射值。zipobservables

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


可观察.zip(可观察量)

(原答:2017年7月)可观察.zip方法在反应式X文档中进行了解释:

组合多个可观察量以创建一个可观察量,其值是根据其每个输入可观察量的值(按顺序)计算的。

// 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();
       })

答案 2

使用可观察量的方法。查看此链接以供参考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