【问题标题】:Observable vs Promise, how to wait for all observables to complete?Observable vs Promise,如何等待所有可观察对象完成?
【发布时间】:2020-03-13 19:45:35
【问题描述】:

在 Node.js 中,我需要等待几个 Observables 完成。我还需要订阅每个 observable。

我会使用Promise.all(),但那些是Observables 而不是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'。为什么它不起作用?

你也看到了,在两个 observables 中我也有一个 promise。如何也等待它(当两个可观察对象和一个承诺都完成时)?

【问题讨论】:

    标签: javascript node.js asynchronous promise observable


    【解决方案1】:

    你的意思是像zip这样的东西?

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

    将上述链接中的示例复制到 stackblitz。希望对你有帮助

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

    【讨论】:

    • 你能举个例子吗?
    • 您正在使用订阅。不要在单个可观察对象上使用它。使用管道,以便它们可以返回值。
    • 举个代码例子:我不明白如何使用pipe()。
    • "管道用于将功能运算符组合成一个链。"但是如何检查个别事件呢?我需要检查事件,而不是管道。为什么不使用订阅?请提供代码示例。
    • 我需要一个小时才能拿到我的笔记本电脑。那就发个例子
    【解决方案2】:

    我认为 forkJoin 是您正在寻找的运算符。它是最接近 Promise.all() 的操作符。它等待所有 observables 完成,然后给你所有的值一次。像这样使用它:

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

    请注意,在所有可观察对象完成之前,forkJoin 不会发出任何内容。如果你想获取所有 observables 发出的值,而不仅仅是最后一个,你可以使用 forkJoin 的兄弟 combineLatest,比如:

    combineLatest(observable1, observable2, observable3)

    要回答有关在流中添加承诺的附带问题,您可以使用 from 运算符来完成,如下所示:

    forkJoin(observable1, observable, from(myPromise) )

    【讨论】:

      【解决方案3】:

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

      根据https://rxjs.dev/guide/observable,Observables 和 Promises 用于两个不同的用例。如果你说“我知道如何通过 Promise 做到这一点”,那么答案可能就是 Promise 是正确的解决方案。

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

      如果您只需要执行步骤 A、B 和 C,并且当它们完成后,使用步骤 D 的结果,那就是 Promise 而不是 Observables。

      如果您只关心完成时会发生什么,那么您可能真的只是想要一个承诺。

      也就是说,我认为 Observables 具有“传染性”,也就是说,一旦你掌握了它,就必须继续使用它们。使用“toPromise”总是有点冒险,因为它会假设 observable 将如何具有,这不一定是有效的,所以如果你不能将任何底层对象更改为 promise,你可能应该坚持使用 observables。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-03
        • 1970-01-01
        • 2021-11-10
        • 2019-03-01
        • 2019-03-25
        • 1970-01-01
        • 1970-01-01
        • 2018-05-28
        相关资源
        最近更新 更多