可观察者与无极者,如何等待所有可观察者完成?

时间:2020-02-09 06:34:35

标签: javascript node.js asynchronous promise observable

在Node.js中,我需要等待几个Observable完成。我还需要订阅每个可观察的对象。

我会使用Promise.all(),但它们是Observable而非Promise

以下代码正确吗?

let promise1 = observable1.toPromise()
observable1.subscribe(...)
let promise2 = observable2.toPromise()
observable2.subscribe(...)
Promise.all([promise1, promise2]).then(...)

如果不正确,如何更改?

我尝试了以下代码:

      let courtsPromise =
        this.ownedContractHandle.pastEvents({fromBlock: 0, filter: {courtId: this.courtIDs}})
          .subscribe(events => this.processCourtEvents(events))
      let namesPromise =
        this.courtNamesContractHandle.pastEvents({fromBlock: 0, filter: {ourCourtId: this.props.courtId}})
          .subscribe(events => this.processNameEvents(events))
      let trustedCourtsPromise =
        this.ownedContractHandle.getTrustedCourtsList(this.props.courtId)
      console.log('before zip')
      zip([courtsPromise, namesPromise]).subscribe(function(values) {
        console.log('values', values)
        this.updateCourtItems()
        this.updateTokenNames()
        this.updateTrustedCourts(values[2])
      })

它打印'before zip',但不打印'values'。为什么它不起作用?

您还看到,在两个可观察变量中,我也有一个承诺。也要如何等待(当两个可观察对象和一个应许都完成时)?

3 个答案:

答案 0 :(得分:5)

您的意思是类似zip的东西?

参考:https://www.learnrxjs.io/learn-rxjs/operators/combination/zip

从上面的链接复制了一个示例到stackblitz。希望对您有帮助

https://stackblitz.com/edit/rxjs-cb55fc?devtoolsheight=60

答案 1 :(得分:3)

我认为forkJoin是您要寻找的运算符。它将是最接近Promise.all()的运算符。它等待所有可观察对象完成,然后为您提供所有值一次。像这样使用它:

forkJoin(observable1, observable2, observable3) .subscribe(([value1, value2, value3]) => { // Do what you want with the values })

请注意,尽管forkJoin在所有可观察对象完成之前不会发出任何东西。如果要获取所有可观察对象发出的值,而不仅仅是最后一个,则可以使用forkJoin的同胞,其名称为CombineLatest,例如:

combineLatest(observable1, observable2, observable3)

要回答有关在流中添加promise的附带问题,您可以使用from运算符来做到这一点,就像这样:

forkJoin(observable1, observable, from(myPromise) )

答案 2 :(得分:1)

这实际上应该是评论,而不是答案(并且要迟到一个月,确实是针对其他读者的),但是当面对这个问题时,问题实际上可能不是您需要等待所有可观察的事物完成,而是您的可观察物实际上应该是应许。

根据https://rxjs.dev/guide/observable,可观察和承诺适用于两种不同的用例。如果您说“我知道如何用诺言做到这一点”,那么答案可能就是诺言是正确的解决方案。

我不能肯定地说,但是基于函数的名称(pastEvents和getTrustedCourtList,听起来很像基本的“ getter”类型的功能),以及使用它们的方式看起来很多,重新使用Observables协调异步工作。这就是诺言的目的。

如果您只需要执行步骤A,B和C,并在它们完成后使用步骤D的结果,那将是不可观察的。

如果您只在乎完成时会发生什么,那么您真的很可能只希望一个诺言。

也就是说,我的观点是Observables具有“传染性”,也就是说,一旦获得,就必须继续使用它们。使用“ toPromise”总是有一定风险,因为它对可观察对象的状态进行了假设,但不一定有效,因此,如果您不能更改promise的基础对象,则您应该坚持可观察对象。