我使用的库使用回调对象发出一系列Message
个对象。
interface MessageCallback {
onMessage(Message message);
}
使用一些libraryObject.setCallback(MessageCallback)
调用添加回调,并使用非阻塞libraryObject.start()
方法调用启动该过程。
创建将发出这些对象的Observable<Message>
的最佳方法是什么?
如果libraryObject.start()
阻止了怎么办?
答案 0 :(得分:2)
我认为你需要这样的东西(在scala中给出的例子)
import rx.lang.scala.{Observable, Subscriber}
case class Message(message: String)
trait MessageCallback {
def onMessage(message: Message)
}
object LibraryObject {
def setCallback(callback: MessageCallback): Unit = {
???
}
def removeCallback(callback: MessageCallback): Unit = {
???
}
def start(): Unit = {
???
}
}
def messagesSource: Observable[Message] =
Observable((subscriber: Subscriber[Message]) ⇒ {
val callback = new MessageCallback {
def onMessage(message: Message) {
subscriber.onNext(message)
}
}
LibraryObject.setCallback(callback)
subscriber.add {
LibraryObject.removeCallback(callback)
}
})
至于阻塞/非阻塞start()
:通常基于回调的体系结构将回调订阅和进程启动分开。在这种情况下,您可以完全独立于messageSource
进程创建任意数量的start()
。你决定是否分叉也是完全正确的。你的架构与此不同吗?
您还应该以某种方式完成整个过程。最好的方法是在MessageCallback接口中添加onCompleted
处理程序。如果要处理错误,还要添加onError
处理程序。现在,你刚刚宣布了RxJava的基本建筑石,Observer: - )
答案 1 :(得分:2)
我们可以像这样将其转换为Observable(RxJava 2的例子):
Observable<Message> source = Observable.create(emitter -> {
MessageCallback callback = message -> emitter.onNext(message);
libraryObject.setCallback(callback);
Schedulers.io().scheduleDirect(libraryObject::start);
emitter.setCancellable(() -> libraryObject.removeCallback(callback));
})
.share(); // make it hot
share
使这个可观察的热,即多个订阅者将共享单个订阅,即最多只有一个回调注册libraryObject
。
我使用io
调度程序来安排从后台线程调用start
,因此它不会延迟首次订阅。
这也很常见。我们假设我们有以下回调式异步方法:
libraryObject.requestDataAsync(Some parameters, MessageCallback callback);
然后我们可以像这样将其转换为Observable(RxJava 2的例子):
Observable<Message> makeRequest(parameters) {
return Observable.create(emitter -> {
libraryObject.requestDataAsync(parameters, message -> {
emitter.onNext(message);
emitter.onComplete();
});
});
}