Что я должен сделать, чтобы получить ответ базы данных из этого кода vertx

#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:

С этим кодом существует ряд проблем:

  1. getDatabaseUsers проглатывает ошибки. Вы, вероятно, хотите сделать pHandler.fail(res.failure()) ; или что-то подобное.
  2. Этот код: 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());
    }
    ...
});
  

Я бы действительно рекомендовал ознакомиться с этим руководством, поскольку оно охватывает именно ваш случай.