正确使用RxJava删除Vert.x回调

时间:2018-08-15 11:24:21

标签: rx-java rx-java2 vert.x

我们正在将 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的反应功能来重组示例代码,从而避免嵌套的回调?

谢谢

2 个答案:

答案 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中的一个大话题,但这是基本思想..接受每个回调

  • 使用正确的运算符将每个逻辑步骤转换为Rx步骤。
  • 进行每个回调错误处理,并将其放入流中。