当前位置: 首页 > 知识库问答 >
问题:

垂直。x的Future获取null值,因为在Future完成之前已触发处理程序

彭风华
2023-03-14

我正在努力理解Vert。x framework和我的任务是创建HTTP服务器,该服务器将执行简单的数学计算,并创建一个客户端,该客户端将向该服务器发送多个请求。我需要计算发送所有请求和获得响应所需的时间。我成功地创建了客户机、服务器,并发送请求和检索响应,但在衡量执行这些操作所需的时间方面存在问题。

我的客户端verticle具有以下方法

@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.");
                        }
                    });
            }));
    }

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

现在,我发现我需要在向客户端发送请求之前设置开始时间,然后在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功能。

共有1个答案

邹俊友
2023-03-14

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

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