2016-05-17 7 views
6

Я пытаюсь связать вызовы/результаты методов со следующим вызовом. Я получаю метод ошибки времени компиляции, потому что если мне не удается получить ссылку objB на предыдущий вызов.CompletableFuture chaining results

Как передать результат предыдущего вызова следующей цепочке? Неужели я полностью неправильно понял этот процесс?

Object objC = CompletableFuture.supplyAsync(() -> service.methodA(obj, width, height)) 
    .thenApply(objA -> { 
    try { 
     return service.methodB(objA); 
    } catch (Exception e) { 
     throw new CompletionException(e); 
    } 
}) 
    .thenApply(objA -> service.methodC(objA)) 
    .thenApply(objA -> { 
    try { 
     return service.methodD(objA); // this returns new objB how do I get it and pass to next chaining call 
     } catch (Exception e) { 
      throw new CompletionException(e); 
     } 
    }) 
    .thenApply((objA, objB) -> { 
     return service.methodE(objA, objB); // compilation error 
    }) 
.get(); 
+1

Вы можете иметь свой первый 'thenApply' возвращает кортеж для хранения как objA и результат methodB. Или, поскольку вы используете 'thenApply', а не' thenApplyAsync', объединение последовательных вызовов 'thenApply' в один лямбда является функционально эквивалентным и дает вам необходимую гибкость. –

+0

Кстати, поскольку вы используете' CompletableFuture' (или 'CompletionStage'), Я заменил бы 'get()' завершением (например, через 'whenComplete (...)' или 'handle (...)'), который выполнил бы последний шаг, например, планируя будущее для Исполнитель пользовательского интерфейса или генерирование и возврат DTO в веб-службе (либо в режиме sucess, либо в качестве исключения, сообщая об ошибке). Как правило, избежать блокировки - это лучшая «инвестиция» по сравнению с чем-либо, что может предложить фьючерс на Java (хотя все остальное тоже полезно). – acelent

ответ

6

Вы можете хранить в переменной промежуточной CompletableFuture, а затем использовать thenCombine:

CompletableFuture<ClassA> futureA = CompletableFuture.supplyAsync(...) 
    .thenApply(...) 
    .thenApply(...); 

CompletableFuture<ClassB> futureB = futureA.thenApply(...); 

CompletableFuture<ClassC> futureC = futureA.thenCombine(futureB, service::methodE); 

objC = futureC.join(); 
Смежные вопросы