Reputation: 320
I have a rest API function which returns an object of type DeferredResult.
import org.springframework.web.context.request.async.DeferredResult;
public DeferredResult<Object> apiMethod{
CompletableFuture<Object> future = someMethod();
final DeferredResult<Object> response = new DeferredResult<>();
future.thenAccept(){
//logic to populate response
}
return response;
}
I am writing a function which will invoke apiMethod() and use its response. I always end up getting a null response because response is populated in future.thenAccept (). Is there a way to handle this ?
Upvotes: 1
Views: 1361
Reputation: 4743
The problem is that the method continues the execution while thenAccept
runs async. After you call thenAccept
, the method just returns response
afterwards, independent of if it's already populated.
Imagine the following simple code:
public static void main(String[] args) {
AtomicReference<String> result = new AtomicReference<>(null);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
for (int i = 0; i < 100_000_000; i++) {}
return "Hello World!";
});
future.thenAccept(s -> {
result.compareAndSet(null, s);
});
System.out.println(result.get());
}
You may expect that "Hello World!"
is printed, which is not the case; it prints out null
. Here's the same problem: the main-thread prints the value, which will be updated async somewhen. You can fix this by joining the future:
public static void main(String[] args) {
AtomicReference<String> result = new AtomicReference<>(null);
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
for (int i = 0; i < 100_000_000; i++) {}
return "Hello World!";
});
CompletableFuture<Void> end = future.thenAccept(s -> {
result.compareAndSet(null, s);
});
end.join();
System.out.println(result.get());
}
Now when we join the async future chain, or rather the one future that sets the value, we will see the main-thread printing out "Hello World!"
because it will wait for the future to finish.
Now you just have to apply this fix in your code.
Upvotes: 1