java - Vert.x 的 Future 获取 null 值,因为处理程序在 future 完成之前被触发

标签 java asynchronous future vert.x vertx-httpclient

我正在尝试了解 Vert.x 框架,我的任务是创建 HTTP 服务器,该服务器将执行简单的数学计算,以及一个客户端,该客户端将向该服务器发送多个请求。我需要计算发送所有请求并获得响应所需的时间。我设法创建客户端、服务器并发送请求和检索响应,但在测量执行这些操作所需的时间时遇到问题。

我的客户端 verticle 有以下 start() 方法:

@Override
    public void start() throws Exception {

        WebClient client = WebClient.create(vertx);

        IntStream.range(0, MathClientApp.REQUEST_NUMBER)
            .forEach(i -> Arrays.stream(Operations.values()).forEach(operation -> {

                client
                    .get(8080, "localhost", operation.getPath())
                    .addQueryParam("numbers", StringUtils.join(numbers, ","))
                    .send(result -> {
                        if (result.succeeded()) {
                            Double mathResult = Double.parseDouble(result.result().bodyAsString());
                            if (mathResult.equals(operation.result(numbers))) {
                                System.out.println("Result: " + result.result().bodyAsString() + " OK!");
                            } else {
                                System.out.println("Result: " + result.result().bodyAsString() + " WRONG!");
                            }
                        } else {
                            System.out.println("Communication failed.");
                        }
                    });
            }));
    }

Operations 是一个枚举,包含服务器可以执行的所有数学运算。

现在,我发现我需要在向客户端发送请求之前设置开始时间,然后在 send() 回调上设置结束时间。因为操作是异步的,所以在计算差值的那一刻可能不会设置结束时间,所以我认为这个结束时间需要是 Future 对象。所以我添加了一些代码:

@Override
    public void start() throws Exception {

        WebClient client = WebClient.create(vertx);

        IntStream.range(0, MathClientApp.REQUEST_NUMBER)
            .forEach(i -> Arrays.stream(Operations.values()).forEach(operation -> {

                Long startTime = System.currentTimeMillis();
                Future<Long> endTime = Future.future(future -> {
                    times.add(future.result() - startTime);
                });

                client
                    .get(8080, "localhost", operation.getPath())
                    .addQueryParam("numbers", StringUtils.join(numbers, ","))
                    .send(result -> {
                        if (result.succeeded()) {
                            endTime.complete(System.currentTimeMillis());
                            Double mathResult = Double.parseDouble(result.result().bodyAsString());
                            if (mathResult.equals(operation.result(numbers))) {
                                System.out.println("Result: " + result.result().bodyAsString() + " OK!");
                            } else {
                                System.out.println("Result: " + result.result().bodyAsString() + " WRONG!");
                            }
                        } else {
                            System.out.println("Communication failed.");
                        }
                    });
            }));
    }

我的理解如下:在每次请求之前,我都会以毫秒为单位获取当前时间,并使用处理程序创建 Future 来结束时间,该处理程序将在出现结束时间时减去这些时间。然后发送请求,并在收到响应时设置结束时间,因此调用 Future 的处理程序方法,减去时间并将其保存到所有请求的所有时间列表中。

但是我在 Future 的处理程序方法中收到 NullPointerException。它在调用服务器之前执行,因此该值尚不存在。我不明白为什么,Vert.x 的官方文档也没有具体说明如何使用这个 Future 功能。

最佳答案

您应该检查 future 是否在处理程序方法内完成。所以它看起来像这样:

Future<Long> endTime = Future.future(future -> {
    if(future.succeeded()) {
        times.add(future.result() - startTime);
    }
});

关于java - Vert.x 的 Future 获取 null 值,因为处理程序在 future 完成之前被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49181245/

相关文章:

java - 在 Java 中,嵌套类与其外部类之间的关系是什么?

java - .zip 文件不会被删除,但也不会引发任何异常

java - 使用 POST 方法发送 JSON 对象

java - 如果我有选择操作,谁能告诉我如何测试我的 Camel 路线?

node.js - 如何在 Node Js 中将 A-lib 与 fastify 一起使用

flutter - 无法在dart中的then函数中将值分配给外部函数变量

c++ - 如何将 std::future<T> 转换为 std::future<void>?

java - 如何使用ExecutorService获取所有提交任务的结果?

scala - 访问 scala future 返回的值

c++ - boost::asio async_read_some async_read_until 编译器警告