I am trying to chain the calls/results of the methods to the next call. I get compile time error methodE because if am not able to get the reference of objB from the previous call.
How can I pass the result of the previous call to the next chain? Have I completely misunderstood the process?
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();
The CompletableFuture. get() method is blocking. It waits until the Future is completed and returns the result after its completion.
CompletableFuture is inherently thread-safe The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation.
supplyAsync. Returns a new CompletableFuture that is asynchronously completed by a task running in the given executor with the value obtained by calling the given Supplier.
While using Future, we do not get notified when it is complete neither does it provides us a callable method which will automatically be called when the result is available but CompletableFuture provides us with a lot of callable methods which can be used as per our use case.
You should use thenCompose, which is an asynchronous mapping, as opposed to thenApply, which is synchronous. Here's an example that chains two future-returning functions:
public CompletableFuture<String> getStringAsync() {
return this.getIntegerAsync().thenCompose(intValue -> {
return this.getStringAsync(intValue);
});
}
public CompletableFuture<Integer> getIntegerAsync() {
return CompletableFuture.completedFuture(Integer.valueOf(1));
}
public CompletableFuture<String> getStringAsync(Integer intValue) {
return CompletableFuture.completedFuture(String.valueOf(intValue));
}
With thenApply you don't return a future. With thenCompose, you do.
You could store intermediate CompletableFuture
in a variable and then use thenCombine
:
CompletableFuture<ClassA> futureA = CompletableFuture.supplyAsync(...)
.thenApply(...)
.thenApply(...);
CompletableFuture<ClassB> futureB = futureA.thenApply(...);
CompletableFuture<ClassC> futureC = futureA.thenCombine(futureB, service::methodE);
objC = futureC.join();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With