Search code examples
javalambdacompletable-futurecompletion-stage

using CompletionStage instead of CompletableFuture


given the following method:

private static String getChuckNorrisJoke () {
    try {
        HttpURLConnection con = (HttpURLConnection) new
        URL( "http://api.icndb.com/jokes/random" ).openConnection();
        BufferedReader in = new BufferedReader( new InputStreamReader(con.getInputStream()));
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = in.readLine()) != null ) {
            response.append(line);
        }
        in.close();
        return response.toString();
    } catch (IOException e) {
        throw new IllegalStateException( "Something is wrong: " , e);
    }
}

the following statement can be used to run the method in an asynchronous fashion.

final CompletableFuture<String> jokeAsync = CompletableFuture.supplyAsync(() -> getChuckNorrisJoke());

although I think that I understand CompletionStage relation to CompletableFuture, I am not sure how I can use CompletionStage to accomplish same task.

final CompletionStage<String> jokeAsync = ?

also, I am not sure about "combining stages"


Solution

  • CompletionStage is the interface implemented by CompletableFuture, so you can just declare jokeAsync as a CompletionStage and it will work:

    final CompletionStage<String> jokeAsync = CompletableFuture.supplyAsync(() -> getChuckNorrisJoke());
    

    If you have several stages, you can combine them in different ways, like:

    The CompletionStage API does not offer some operations that are only provided by CompletableFuture:

    • submitting tasks, e.g. with supplyAsync()
    • combining many stages with allOf() and anyOf()
    • programmatically completing stages or creating already completed stages
    • waiting for a stage's result with join() or get()

    But the toCompletableFuture() allows to convert any stage and thus bridge the gap.