如何使用在方法内部的 Java 匿名函数中获得的数据
How to use data obtained in a Java anonymous function that is inside of a method
似乎是个常见问题,但我不确定解决方案。
我正在使用 Vert.x 和 Java 来调用另一个服务。我正在使用 Vert.x 的 WebClient
库。当我发出 POST
请求时,参数之一是匿名函数。如果请求成功,那么我就得到了我的数据。
问题是在我方法的其余部分中,在匿名函数之外获取此数据。我希望我的方法 return 从我的匿名函数获得的数据。数据在 body
变量中。
private JsonArray itemTypes() {
WebClient webClient = WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
JsonArray body = result.body();
} else {
System.out.println(ar.cause().getMessage());
}
});
}
现在,如果我尝试在匿名函数外部声明 body
变量并在内部分配它(这样我就可以 return 值),我的 IDE 会抱怨Local variable body defined in an enclosing scope must be final or effectively final
.
我基本上想做这样的事情:
private JsonArray itemTypes() {
JsonArray body;
WebClient webClient = WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
body = result.body();
} else {
System.out.println(ar.cause().getMessage());
body = new JsonArray();
}
});
return body;
}
我试过使 JsonArray 主体变量成为最终变量,但这不起作用。我还尝试将整个 webClient.post(....)
调用分配给一个变量,但这也不起作用。
如何在匿名函数之外访问 body
数据,以便在我的方法中 return 它?
您遇到的问题是 WebClient 似乎是完全异步的。这意味着当你调用.sendJsonObject
时,它基本上发送请求并立即returns;当 WebClient 等待答案时,您的代码保持 运行ning。
收到响应后,它会调用您提供的回调 lambda,可能在其他线程中。这可能会在几秒钟后发生,同时您的许多其他代码可能有时间 运行。
您需要的是让您的主代码等待收到响应。这可以通过多种方式完成,其中之一是创建一个 CompletableFuture<T>
,让回调调用 .complete(theValue)
方法,然后让外部代码调用 .get()
等待和接收值。
换句话说,外部代码将定义并等待 CompletableFuture<T>
完成,然后让 .sendJsonObject
回调为您完成所需的值。
可以这样做:
private Future<JsonArray> itemTypes() {
Future<JsonArray> body = Future.future();
WebClient webClient =
WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
body.complete(result.body());
} else {
System.out.println(ar.cause().getMessage());
body.fail(ar.cause());
}
});
return body;
}
然后在返回的 future 上设置一个处理程序。如果您愿意,您也可以在将来使用处理程序传递:
private void itemTypes(Future<JsonArray> body) {
似乎是个常见问题,但我不确定解决方案。
我正在使用 Vert.x 和 Java 来调用另一个服务。我正在使用 Vert.x 的 WebClient
库。当我发出 POST
请求时,参数之一是匿名函数。如果请求成功,那么我就得到了我的数据。
问题是在我方法的其余部分中,在匿名函数之外获取此数据。我希望我的方法 return 从我的匿名函数获得的数据。数据在 body
变量中。
private JsonArray itemTypes() {
WebClient webClient = WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
JsonArray body = result.body();
} else {
System.out.println(ar.cause().getMessage());
}
});
}
现在,如果我尝试在匿名函数外部声明 body
变量并在内部分配它(这样我就可以 return 值),我的 IDE 会抱怨Local variable body defined in an enclosing scope must be final or effectively final
.
我基本上想做这样的事情:
private JsonArray itemTypes() {
JsonArray body;
WebClient webClient = WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
body = result.body();
} else {
System.out.println(ar.cause().getMessage());
body = new JsonArray();
}
});
return body;
}
我试过使 JsonArray 主体变量成为最终变量,但这不起作用。我还尝试将整个 webClient.post(....)
调用分配给一个变量,但这也不起作用。
如何在匿名函数之外访问 body
数据,以便在我的方法中 return 它?
您遇到的问题是 WebClient 似乎是完全异步的。这意味着当你调用.sendJsonObject
时,它基本上发送请求并立即returns;当 WebClient 等待答案时,您的代码保持 运行ning。
收到响应后,它会调用您提供的回调 lambda,可能在其他线程中。这可能会在几秒钟后发生,同时您的许多其他代码可能有时间 运行。
您需要的是让您的主代码等待收到响应。这可以通过多种方式完成,其中之一是创建一个 CompletableFuture<T>
,让回调调用 .complete(theValue)
方法,然后让外部代码调用 .get()
等待和接收值。
换句话说,外部代码将定义并等待 CompletableFuture<T>
完成,然后让 .sendJsonObject
回调为您完成所需的值。
可以这样做:
private Future<JsonArray> itemTypes() {
Future<JsonArray> body = Future.future();
WebClient webClient =
WebClient.create(vertx);
webCLient.post(80, "myApi.com", "/api/items")
.sendJsonObject(new JsonObject().put("mutator", "*"), ar -> {
if (ar.succeeded) {
HttpResponse<JsonArray> result = ar.result();
body.complete(result.body());
} else {
System.out.println(ar.cause().getMessage());
body.fail(ar.cause());
}
});
return body;
}
然后在返回的 future 上设置一个处理程序。如果您愿意,您也可以在将来使用处理程序传递:
private void itemTypes(Future<JsonArray> body) {