Vert.x 的 Future 获得空值,因为在 future 完成之前触发了处理程序
Vert.x's Future gets null value because handler is fired before the future's complete
我正在尝试了解 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);
}
});
我正在尝试了解 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);
}
});