How can I `await` on an Rx Observable?
我希望能够等待一个可观测的,例如
1 2 3
| const source = Rx.Observable.create(/* ... */)
//...
await source; |
幼稚的尝试会导致等待立即解决,而不会阻止执行。
编辑:我的完整预期用例的伪代码是:
1 2 3 4
| if (condition) {
await observable;
}
// a bunch of other code |
号
我知道我可以将其他代码移动到另一个单独的函数中,并将其传递到订阅回调,但我希望能够避免这种情况。
- 您不能将剩余的代码(您希望等待源代码)移动到.subscribe()方法调用中吗?
你必须向await承诺。把观察到的下一个事件转化为承诺,然后等待。
1 2 3
| if (condition) {
await observable.first().toPromise();
} |
编辑说明:此答案最初是使用的。Take(1),但改为使用.First(),这避免了如果流在值通过之前结束,则承诺永远不会解决的问题。
- 你能用await observable.first().toPromise();代替take(1)吗?
- @杏的味道应该是一样的。
- @先验性如果完成时没有价值,first()将导致拒绝,take(1)将导致未决承诺。
- @埃斯图斯:所以,一般来说,叫first()更合理,对吧?
- @apricity@agentme实际上,在这种情况下,您不应该使用take(1)或first()。因为您只希望发生一个事件,所以应该使用single(),如果有一个以上的异常,它将抛出一个异常,而如果没有异常,则不抛出异常。如果代码/数据模型中存在多个错误等,那么如果不使用单个,则最终会随意选择返回的第一个项目,而不会警告存在更多项目。您必须注意上游数据源上的谓词,以始终保持相同的顺序。
- @ntziolis注意到.single()会一直等到源流结束,然后再输出值和结束,这可能在.first()或.take(1)可以工作的所有情况下都不能很好地工作。
- 别忘了进口:import 'rxjs/add/operator/first';。
- 既然toppromise()已被弃用,那么我们应该怎么做呢?
必须是
1
| await observable.first().toPromise(); |
号
正如之前的评论中所指出的,当可观测到空的完整数据时,take(1)和first()运算符之间存在实质性差异。
Observable.empty().first().toPromise()将导致可以相应处理的EmptyError的拒绝,这通常是一种可取的行为。
而Observable.empty().take(1).toPromise()将导致未决承诺,这是可取的……几乎从来没有。
你需要await一个承诺,所以你需要使用toPromise()。有关toPromise()的更多详细信息,请参阅此部分。