我正在研究一个swagger生成的Java API。在生成的客户机文件中,我看到如下两个方法:
public Observable<UserAccountView> createUserAccount(/* params omitted */) {
/* body omitted */
}
public UserAccountView createUserAccountSynchronously(/* params omitted */) {
return createUserAccount(/*params*/).toBlocking.single();
}
我已经阅读了RxJava文档和相关资源,但因为我是新手,我仍然发现自己认为toBlocking
不应该在这里被需要——阻塞/非阻塞是否失去了它对单个的意义?有没有所谓的"拦网单曲"?
显然我没有完全理解这两种方法之间的关系。我认为single()
在取消订阅之前从可观察对象中提取奇异事件。为什么需要toBlocking
才能做到这一点?
toBlocking()
调用在那里,因此该方法返回UserAccountView
而不是Observable<UserAccountView>
。toBlocking()
将Observable
转换为BlockingObservable
,调用BlockingObservable.single()
返回BlockingObservable
发出的任何项,只要它在完成之前只发出一个项(多于或少于一个将导致发出错误)。
如果你在RxJava1中调用Observable.single()
而不将其转换为BlockingObservable
,如果Observable在发出一个项目后完成,它将返回一个只发出一个项目的Observable<UserAccountView>
。在RxJava2中,该API得到了改进,以便等价的操作符Observable.singleOrError()
返回Single<UserAccountView>
。
阻塞/非阻塞对于Single
(或者在这种情况下,Observable
只会发出单个项)并没有失去它的意义。根据你如何设置你的调度器(例如使用subscribeOn()
,observeOn()
或使用Scheduler
的操作符),你可以有一个Single
/Observable
,在一些工作线程中做处理后,只异步地发出它的一个项目。因此,如果createUserAccount()
的调用者在应用程序的主线程中运行,那么Observable<UserAccountView>
可以立即返回,并在几秒钟后在下游的工作线程上发出其结果,而不会阻塞主线程。另一方面,使用createUserAccountSynchronously()
将阻塞主线程,直到Observable<UserAccountView>
发出它的一个项目。
通常在响应式应用程序中,你会避免使用toBlocking()
,但有时你需要在响应式世界和非响应式阻塞世界之间架起一座桥梁,这就是toBlocking()
可以派上用场的地方。