Верт.x, передающий будущее без исполнения

#java #asynchronous #future #vert.x

Вопрос:

У меня есть приведенный ниже фрагмент кода:

 package starter;

import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;

public class MainVerticle extends AbstractVerticle {

  @Override
  public void start() {
    vertx.createHttpServer().requestHandler(req -> req.response().end("Hello Vert.x!")).listen(8080);

    cacheFirst("key", Future.future(h -> {
      System.out.println("Call external API");
      h.complete("Call external API");
    }))
    .onComplete(h -> System.out.println("Success"))
    .onFailure(t -> System.out.println("Failed"));
  }

  private Future<String> cacheFirst(String key, Future<String> task) {
    Future<String> getCache = Future.future(h -> {
      h.complete("ABCXYZ");
    });

    return getCache.onSuccess(res -> {
      System.out.println("Data from cache: "   res);
    }).onFailure(t -> {
      task.onSuccess(res -> {
        System.out.println("Store task result to cache");
      }).onFailure(tt -> {
        System.out.println("Do nothing");
      });
    });
  }

}
 

Ожидаемый вывод консоли:

 Data from cache: ABCXYZ
Success
 

Фактический вывод на консоль:

 Call external API
Data from cache: ABCXYZ
Success
 

В функции start , как я могу передать Future cacheFirst функцию в качестве аргумента без ее выполнения?

В реальном сценарии cacheFirst функция сначала попытается получить данные из хранилища кэша, и если они будут найдены, не потребуется выполнять предусмотренную функцию future ( Future<string> task ), например, для вызова запроса к внешнему API.

Репродуктор: https://github.com/triet-truong/vertx-application

Ответ №1:

Просто заверните его внутрь Supplier и получите ожидаемый результат!
https://github.com/triet-truong/vertx-application/commit/6391c1b5d6b5f0e9b927ab0a9834b3ce6f0edf7f

 cacheFirst("key", () -> Future.future(h -> {
      System.out.println("Call external API");
      h.complete("Call external API");
    }))
    .onComplete(h -> System.out.println("Success"))
    .onFailure(t -> System.out.println("Failed"));
 
 private Future<String> cacheFirst(String key, Supplier<Future<String>> task) {
    Future<String> getCache = Future.future(h -> {
      h.complete("ABCXYZ");
    });

    return getCache.onSuccess(res -> {
      System.out.println("Data from cache: "   res);
    }).onFailure(t -> {
      task.get().onSuccess(res -> {
        System.out.println("Store task result to cache");
      }).onFailure(tt -> {
        System.out.println("Do nothing");
      });
    });
  }