#vert.x
#vert.x
Вопрос:
Это метод, используемый для подключения к базе данных и получения результатов:
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], а метод базы данных еще не завершен.
Итак, что я должен сделать, чтобы дождаться ответа базы данных, а затем отправить ответ клиенту?
Ответ №1:
С этим кодом существует ряд проблем:
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());
}
...
});
Я бы действительно рекомендовал ознакомиться с этим руководством, поскольку оно охватывает именно ваш случай.