在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'
。为什么它不起作用?
您还看到,在两个可观察变量中,我也有一个承诺。也要如何等待(当两个可观察对象和一个应许都完成时)?
答案 0 :(得分:5)
您的意思是类似zip的东西?
参考:https://www.learnrxjs.io/learn-rxjs/operators/combination/zip
从上面的链接复制了一个示例到stackblitz。希望对您有帮助
答案 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的基础对象,则您应该坚持可观察对象。