## Future results

Vert.x 4 use futures to represent asynchronous results.

Any asynchronous method returns a `Future` object for the result of the call: a success or a failure.

You cannot interact directly with the result of a future, instead you need to set a handler that will be called when the future completes and the result is available, like any other kind of event.

    FileSystem fs = vertx.fileSystem();

    Future<FileProps> future = fs.props("/my_file.txt");

    future.onComplete((AsyncResult<FileProps> ar) -> {
      if (ar.succeeded()) {
        FileProps props = ar.result();
        System.out.println("File size = " + props.size());
      } else {
        System.out.println("Failure: " + ar.cause().getMessage());
      }
    });

Note | Vert.x 3 provides a callback-only model. To allow an easy migration to Vert.x 4 we decided that each asynchronous method has also a callback version. The `props` method above has also a version `props` with a callback as method argument.

Caution | Do not confuse futures with promises. If futures represent the "read-side" of an asynchronous result, promises are the "write-side". They allow you to defer the action of providing a result. In most cases, you don’t need to create promises yourself in a Vert.x application. Future composition and Future coordination provide you with the tools to transform and merge asynchronous results. However, if, in your codebase, you have legacy methods which use callbacks, you can leverage the fact that a promise extends `io.vertx.core.Handler<io.vertx.core.AsyncResult>`:
    Promise<String> promise = Promise.promise();
    legacyGreetAsync(promise);
    Future<String> greeting = promise.future();

Caution | Terminal operations like `onSuccess`, `onFailure` and `onComplete` provide no guarantee whatsoever regarding the invocation order of callbacks. Consider a future on which 2 callbacks are registered:
    future.onComplete(ar -> {
      // Do something
    });
    future.onComplete(ar -> {
      // May be invoked first
    });
It is possible that the second callback is invoked before the first one. If you need such guarantee, consider using Future composition with `andThen`.

## Future composition

`compose` can be used for chaining futures:

- when the current future succeeds, apply the given function, that returns a future. When this returned future completes, the composition succeeds.

- when the current future fails, the composition fails

    FileSystem fs = vertx.fileSystem();

    Future<Void> future = fs
      .createFile("/foo")
      .compose(v -> {
        // When the file is created (fut1), execute this:
        return fs.writeFile("/foo", Buffer.buffer());
      })
      .compose(v -> {
        // When the file is written (fut2), execute this:
        return fs.move("/foo", "/bar");
      });

In this example, 3 operations are chained together:

1. a file is created

2. data is written in this file

3. the file is moved

When these 3 steps are successful, the final future (`future`) will succeed. However, if one of the steps fails, the final future will fail.

Beyond this, `Future` offers more: `map`, `recover`, `otherwise`, `andThen` and even a `flatMap` which is an alias of `compose`

## Future coordination

Coordination of multiple futures can be achieved with Vert.x `futures`. It supports concurrent composition (run several async operations in parallel) and sequential composition (chain async operations).

`CompositeFuture.all` takes several futures arguments (up to 6) and returns a future that is succeeded when all the futures are succeeded and failed when at least one of the futures is failed:

    Future<HttpServer> httpServerFuture = httpServer.listen();

    Future<NetServer> netServerFuture = netServer.listen();

    CompositeFuture.all(httpServerFuture, netServerFuture).onComplete(ar -> {
      if (ar.succeeded()) {
        // All servers started
      } else {
        // At least one server failed
      }
    });

The operations run concurrently, the `Handler` attached to the returned future is invoked upon completion of the composition. When one of the operation fails (one of the passed future is marked as a failure), the resulting future is marked as failed too. When all the operations succeed, the resulting future is completed with a success.

Alternatively, you can pass a list (potentially empty) of futures:

    CompositeFuture.all(Arrays.asList(future1, future2, future3));

While the `all` composition waits until all futures are successful (or one fails), the `any` composition waits for the first succeeded future. `CompositeFuture.any` takes several futures arguments (up to 6) and returns a future that is succeeded when one of the futures is, and failed when all the futures are failed:

    CompositeFuture.any(future1, future2).onComplete(ar -> {
      if (ar.succeeded()) {
        // At least one is succeeded
      } else {
        // All failed
      }
    });

A list of futures can be used also:

    CompositeFuture.any(Arrays.asList(f1, f2, f3));

The `join` composition waits until all futures are completed, either with a success or a failure. `CompositeFuture.join` takes several futures arguments (up to 6) and returns a future that is succeeded when all the futures are succeeded, and failed when all the futures are completed and at least one of them is failed:

    CompositeFuture.join(future1, future2, future3).onComplete(ar -> {
      if (ar.succeeded()) {
        // All succeeded
      } else {
        // All completed and at least one failed
      }
    });

A list of futures can be used also:

    CompositeFuture.join(Arrays.asList(future1, future2, future3));

### CompletionStage interoperability

The Vert.x `Future` API offers compatibility from and to `CompletionStage` which is the JDK interface for composable asynchronous operations.

We can go from a Vert.x `Future` to a `CompletionStage` using the `toCompletionStage` method, as in:

    Future<String> future = vertx.createDnsClient().lookup("vertx.io");
    future.toCompletionStage().whenComplete((ip, err) -> {
      if (err != null) {
        System.err.println("Could not resolve vertx.io");
        err.printStackTrace();
      } else {
        System.out.println("vertx.io => " + ip);
      }
    });

We can conversely go from a `CompletionStage` to Vert.x `Future` using `Future.fromCompletionStage`. There are 2 variants:

1. the first variant takes just a `CompletionStage` and calls the `Future` methods from the thread that resolves the `CompletionStage` instance, and

2. the second variant takes an extra `Context` parameter to call the `Future` methods on a Vert.x context.

Important | In most cases the variant with a `CompletionStage` and a `Context` is the one you will want to use to respect the Vert.x threading model, since Vert.x `Future` are more likely to be used with Vert.x code, libraries and clients.

Here is an example of going from a `CompletionStage` to a Vert.x `Future` and dispatching on a context:

    Future.fromCompletionStage(completionStage, vertx.getOrCreateContext())
      .flatMap(str -> {
        String key = UUID.randomUUID().toString();
        return storeInDb(key, str);
      })
      .onSuccess(str -> {
        System.out.println("We have a result: " + str);
      })
      .onFailure(err -> {
        System.err.println("We have a problem");
        err.printStackTrace();
      });