## 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());
      }
    });

| 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.

| 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).

`Future.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();

    Future.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.

On success, the `resultAt` method guarantees the results in the same order specified in the call to `Future.all`. In the example above, regardless of which item completed first, the `httpServer` result can be accessed using `resultAt(0)` and the `netServer` result can be accessed using `resultAt(1)`.

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

    Future.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. `Future.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:

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

A list of futures can be used also:

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

The `join` composition waits until all futures are completed, either with a success or a failure. `Future.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:

    Future.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:

    Future.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.

| 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();
      });