Создать связанный список CompletableFutures с помощью compose - PullRequest
0 голосов
/ 07 ноября 2018

Я хочу создать цепочку CompletableFutures.

Я пытаюсь создать вещи следующим образом.

Задача 1 выполняет что-то и возвращает строку в качестве результата, когда задача 1 выполнена, я хочу запустить задачу 2 в качестве ввода результатаЗадача 1. Задача 2, когда она готова, она возвращает целое число и так далее ...

Так что это должно быть очень динамично, поэтому у меня уже есть это:

      try {
            CompletableFuture<String> task1Future = CompletableFuture.supplyAsync(new Task1());
            CompletableFuture<String> result = task1Future.thenCompose(task1Result -> CompletableFuture.supplyAsync(new Task2(task1Result)));
            System.out.println(result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }


        public class Task1 implements Supplier<String> {

    public Task1() {
        System.out.println("Task 1 started");
    }

    @Override
    public String get() {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "Result Task 1";
    }
}

Что я знаю попробоватьдобиться - построить Wrapper (своего рода связанный список):

Список задач, где задача должна быть:

public class Task {
    private Supplier startTask;
    private Task followUpTask;

    public Task(Supplier startTask, Task followUpTask) {
        this.startTask = startTask;
        this.followUpTask = followUpTask;
    }
}

Но я застрял, потому что не знаю каксделать цепочку и сделать задачу более общей, чтобы ее можно было начать с любого результата предыдущей задачи.

Так что мне нужен метод для конструирования CompletableFuture и просто сказать start (), и все происходит.

Может кто-нибудь помочь мне в пути?

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

На тот случай, если вы хотите, чтобы все ваши задачи реализовали функцию, вы можете запустить цепочку следующим образом:

CompletableFuture<String> task1Future = CompletableFuture.completedFuture("S")
    .thenApply(new Task1());

где completedFuture("S") содержит аргумент для первой задачи:

public static class Task1 implements Function<String, String>  {

    public Task1() {
        System.out.println("Task 1 started");
    }

    @Override
    public String apply(String s) {
        try {
            TimeUnit.SECONDS.sleep(5);
        } catch (InterruptedException e) {
            throw new IllegalStateException(e);
        }
        return "Result Task 1";
    }
}
0 голосов
/ 07 ноября 2018

Вы должны определить Task2 как функцию, так как она принимает предыдущий результат String и выдает новый результат Integer:

public static class Task2 implements Function<String, Integer> {

    public Task2() {
        System.out.println("Task 2 started");
    }

    @Override
    public Integer apply(String s) {
        return s.length();
    }
}

тогда вы можете связать их следующим образом:

   CompletableFuture<String> task1Future = CompletableFuture.supplyAsync(new Task1());
   CompletableFuture<Integer> result = task1Future.thenApply(new Task2());
   System.out.println(result.get());
...