我们正在将 Vert.x 与 RxJava 一起使用。 我们的应用程序逻辑正在运行,但是,尽管使用了RxJava,该代码仍然包含嵌套在几层深处的回调。 以下是一个示例。为了突出代码的结构,已删除所有日志记录和其他逻辑。
EventBus eb = vertx.eventBus();
// retrieve incoming messages from the consumer by listening on the event bus
MessageConsumer<BusMessage> consumer = eb.<BusMessage>consumer(address);
Observable<Message<BusMessage>> consumerObservable = consumer.toObservable();
consumerObservable.subscribe(cosumedMsg -> {
Object msg = cosumedMsg.body().encode());
Single<Message<MyObject>> step1 = eb.<MyObject>rxSend(addrs1, msg, deliveryOpts));
step1.subscribe(validationRes -> {
Single<Message<MyObject>> step2 = eb.rxSend(addrs2, msg, deliveryOpts));
step2.subscribe(handlerRes -> {
Single<Message<MyObject>> step3 = eb.rxSend(addrs3, msg, deliveryOpts));
step3.subscribe(dsRes -> {
Single<Message<MyObject>> step4 = eb.rxSend(addrs4, msg, deliveryOpts));
step4.subscribe(msg -> {
msg.body();
}, err -> {
// step1 error handling
});
}, err -> {
// step2 error handling
});
}, err -> {
// step3 error handling
});
}, err -> {
// step4 error handling
});
很可能我没有正确使用RxJava。 有没有一种方法可以使用RaxJava的反应功能来重组示例代码,从而避免嵌套的回调?
谢谢
答案 0 :(得分:2)
我认为,Rx链的末尾应该只有一个subscribe()
。
您应该使用flatMap()
链来链接事件总线调用。像这样:
public void start() throws Exception {
EventBus eventBus = vertx.eventBus();
MessageConsumer<BusMessage> consumer = eventBus.consumer("my.address");
Observable<Message<BusMessage>> consumerObservable = consumer.toObservable();
consumerObservable
.flatMapSingle(consumerMsg -> {
final Object msg = consumerMsg.body().encode();
return eventBus.rxSend("addrs1", msg, new DeliveryOptions());
})
.flatMapSingle(step1Msg -> eventBus.rxSend("addrs2", step1Msg, new DeliveryOptions()))
.flatMapSingle(step2Msg -> eventBus.rxSend("addrs3", step2Msg, new DeliveryOptions()))
.subscribe(this::handleFinalMsg,
this::handleException,
this::handleOnComplete);
}
private void handleFinalMsg(final Message<Object> message) {
System.out.println(message.body());
}
private void handleException(final Throwable throwable) {
System.err.println(throwable);
}
private void handleOnComplete() {
System.out.println("it's the end!");
}
任何可能发生的异常都由this::handleException
处理。
您可以查看此博客文章:https://streamdata.io/blog/vert-x-and-the-async-calls-chain/(及其相关代码),并可以查看此代码https://github.com/ctranxuan/howtos-vertx/tree/master/eventbus-rxjava,以获得可能的见识。
我希望这会有所帮助。
答案 1 :(得分:-1)
Rxjava提供了许多运算符以功能方式对逻辑建模,这些嵌套的回调可以使用运算符轻松转换为逻辑链。您不需要在任何运算符处获取错误,因为Rx已经将这些错误放在一个地方,从而可以相应地表现出来。错误处理是Rx中的一个大话题,但这是基本思想..接受每个回调