I want to get a value inside a CompletableFuture (in this case clonedWorld) in another CompletableFuture and return that future. This is my code, and I'm stuck here:
@Override
public CompletableFuture<SlimeWorld> asyncCloneWorld(String worldName, String newWorld) {
loadWorldAsync(worldName).whenComplete((slimeWorld, throwable) -> {
if (throwable != null || slimeWorld.isEmpty()) {
plugin.getLogger().log(Level.SEVERE, "Impossibile caricare il mondo template!", throwable);
return;
}
try {
SlimeWorld clonedWorld = slimeWorld.get().clone(newWorld, loader, true);
} catch (IOException | WorldAlreadyExistsException e) {
plugin.getLogger().log(Level.SEVERE, "Non è stato possibile clonare il mondo: " + worldName, e);
}
});
return ?;
}
Your problem is that whenComplete()
only takes a BiConsumer
as parameter, which cannot handle the result of the returned CompletableFuture
– except if an exception is thrown.
The appropriate method to use if you want to change the result (here from something like Optional<SlimeWorld>
or an exception to just SlimeWorld
or null
) is handle()
. The lambda passed to handle()
should thus return the final result (the cloned world or null
).
And as CompletableFuture
is a fluent API, you can just return the result of the handle()
call from asyncCloneWorld()
:
public CompletableFuture<SlimeWorld> asyncCloneWorld(String worldName, String newWorld) {
return loadWorldAsync(worldName).handle((slimeWorld, throwable) -> {
if (throwable != null || slimeWorld.isEmpty()) {
plugin.getLogger().log(Level.SEVERE, "Impossibile caricare il mondo template!", throwable);
return null;
}
try {
return slimeWorld.get().clone(newWorld, loader, true);
} catch (IOException e) {
plugin.getLogger().log(Level.SEVERE, "Non è stato possibile clonare il mondo: " + worldName, e);
return null;
}
});
}