如何在循环中进行一些异步调用

时间:2016-07-25 11:02:59

标签: java functional-programming vert.x purely-functional

在循环中,我需要进行一些检查,实际上在另一个Verticle中执行。在我的循环的每次迭代中,我需要检查响应代码,从那些Verticle返回并相应地做出一些决定。换句话说,我需要停止循环的执行,并以某种方式等待asynch。呼叫返回。但是这样的执行停止违反了vert.x哲学,该哲学声明主线程执行应该永远不会停止。我怎么能在Vert.x的范围内做到这一点?到目前为止,我不知道该怎么做。任何建议/代码样本/网址。喜欢解决方案会受到高度赞赏。

谢谢!

3 个答案:

答案 0 :(得分:1)

我认为你需要使用FutureTask并将它们存储在Collection中,然后使用count在需要时检索结果,这是一个阻塞调用。

答案 1 :(得分:1)

这听起来像是反应性蒸汽处理的一个用例。 一般来说,这样的问题可以通过2方来解决:

  • 执行任务并返回异步结果的生产者
  • 订阅结果并执行其他任务的处理程序

有一种方法可以将生产者配置为仅在有订户时执行任务。另一方面,订户可以决定在某些条件下取消订阅生产者。

我不熟悉反应流的vertx功能。但我会从RxJava集成开始 http://vertx.io/docs/vertx-rx/java/

答案 2 :(得分:1)

使用Vert.x时,您需要在循环方面考虑较少,在回调方面需要考虑更多。 您应该使用eventBus在顶点之间进行通信。 让我们说你想要的是类似于这个伪代码的东西:

for (int i = 0; i < 4; i++) {
   int result = getVerticleResult();
   System.out.println(result);
}

所以,只是一个非常基本的例子

class LooperVerticle extends AbstractVerticle {

    private int i = 4;

    @Override
    public void start() throws Exception {
        doWork();
    }

    private void doWork() {
        vertx.eventBus().send("channel", "", (o) -> {
            if (o.succeeded()) {
                System.out.println(o.result().body());
                i--;
                if (i > 0) {
                    doWork();
                }
            }
        });
    }
}

class WorkerVerticle extends AbstractVerticle {

    @Override
    public void start() throws Exception {

        vertx.eventBus().consumer("channel", (o) -> {
            // Generate some random number
            int num = ThreadLocalRandom.current().nextInt(0, 9);

            // Simulate slowness
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            o.reply(num);
        });
    }
}

测试:

public class EventBusExample {

    public static void main(String[] args) {
        Vertx vertx = Vertx.vertx();
        vertx.deployVerticle(new LooperVerticle());
        vertx.deployVerticle(new WorkerVerticle());
    }
}