问题描述
public Future<String> getDatabaseUsers(JDBcclient client) {
return Future.future(pHandler -> {
client.getConnection(res -> {
if (res.succeeded()) {
sqlConnection con = res.result();
con.query("select u.id,u.name from users u",rHandler -> {
String data;
if (rHandler.succeeded()) {
data = Json.encode(rHandler.result().getResults());
} else {
data = "Database execution error";
}
con.close();
pHandler.complete(data);
});
} else {
pHandler.complete("Cannot connect to database");
}
});
});
}
private void handleRequest(RoutingContext routingContext,JDBcclient client,Handler<List<String>> resultHandler) {
routingContext.vertx().<String>executeBlocking(pHandler -> {
pHandler.complete(getDatabaseUsers(client).result());
},ar -> {
List<String> responses = new ArrayList<>();
if (ar.succeeded()) {
responses.add(ar.result());
System.out.println(Json.encode(responses)); // Null here
}
resultHandler.handle(responses);
});
}
resultHandler对象用于添加来自其他进程的更多响应;但这实际上不是问题。
这是端点:
router.get("/db").handler(ctx -> handleRequest(
ctx,client,(list) -> ctx.response()
.putHeader("Content-Type","text/plain")
.end(Json.encode(list))));
此代码的问题是服务响应为[null],并且数据库方法尚未完成。 那么,我应该怎么做才能等待数据库响应,然后将响应发送给客户端?
解决方法
此代码存在很多问题:
-
getDatabaseUsers
吞没了错误。您可能想做pHandler.fail(res.failure())
;或类似的东西。 - 此代码:
pHandler.complete(getDatabaseUsers(client).result());
并未按照您认为的去做。result()
不会受阻,因此您可以用另一个未受限制的未来来完成自己的未来。
您真正想要的是相反的情况
getDatabaseUsers(client).handle((r) -> { // This is called when the futures actually completes
if (r.succeeded()) {
pHandler.complete(r.result());
}
...
});