/*
 * Copyright (c) 2011-2017 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

package io.vertx.core;

import io.vertx.codegen.annotations.CacheReturn;
import io.vertx.codegen.annotations.Fluent;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.annotations.VertxGen;
import io.vertx.core.spi.FutureFactory;

import java.util.function.Function;

Represents the result of an action that may, or may not, have occurred yet.

Author:Tim Fox
/** * Represents the result of an action that may, or may not, have occurred yet. * <p> * * @author <a href="http://tfox.org">Tim Fox</a> */
@VertxGen public interface Future<T> extends AsyncResult<T>, Handler<AsyncResult<T>> {
Create a future that hasn't completed yet and that is passed to the handler before it is returned.
Params:
  • handler – the handler
Type parameters:
  • <T> – the result type
Returns:the future.
/** * Create a future that hasn't completed yet and that is passed to the {@code handler} before it is returned. * * @param handler the handler * @param <T> the result type * @return the future. */
static <T> Future<T> future(Handler<Promise<T>> handler) { Promise<T> promise = Promise.promise(); handler.handle(promise); return promise.future(); }
Create a future that hasn't completed yet
Type parameters:
  • <T> – the result type
Returns: the future
Deprecated:instead use Promise.promise()
/** * Create a future that hasn't completed yet * * @param <T> the result type * @return the future * @deprecated instead use {@link Promise#promise()} */
@Deprecated static <T> Future<T> future() { return factory.future(); }
Create a succeeded future with a null result
Type parameters:
  • <T> – the result type
Returns: the future
/** * Create a succeeded future with a null result * * @param <T> the result type * @return the future */
static <T> Future<T> succeededFuture() { return factory.succeededFuture(); }
Created a succeeded future with the specified result.
Params:
  • result – the result
Type parameters:
  • <T> – the result type
Returns: the future
/** * Created a succeeded future with the specified result. * * @param result the result * @param <T> the result type * @return the future */
static <T> Future<T> succeededFuture(T result) { return factory.succeededFuture(result); }
Create a failed future with the specified failure cause.
Params:
  • t – the failure cause as a Throwable
Type parameters:
  • <T> – the result type
Returns: the future
/** * Create a failed future with the specified failure cause. * * @param t the failure cause as a Throwable * @param <T> the result type * @return the future */
static <T> Future<T> failedFuture(Throwable t) { return factory.failedFuture(t); }
Create a failed future with the specified failure message.
Params:
  • failureMessage – the failure message
Type parameters:
  • <T> – the result type
Returns: the future
/** * Create a failed future with the specified failure message. * * @param failureMessage the failure message * @param <T> the result type * @return the future */
static <T> Future<T> failedFuture(String failureMessage) { return factory.failureFuture(failureMessage); }
Has the future completed?

It's completed if it's either succeeded or failed.

Returns:true if completed, false if not
/** * Has the future completed? * <p> * It's completed if it's either succeeded or failed. * * @return true if completed, false if not */
boolean isComplete();
Set a handler for the result.

If the future has already been completed it will be called immediately. Otherwise it will be called when the future is completed.

Params:
  • handler – the Handler that will be called with the result
Returns:a reference to this, so it can be used fluently
/** * Set a handler for the result. * <p> * If the future has already been completed it will be called immediately. Otherwise it will be called when the * future is completed. * * @param handler the Handler that will be called with the result * @return a reference to this, so it can be used fluently * */
@Fluent Future<T> setHandler(Handler<AsyncResult<T>> handler);
Set the result. Any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • result – the result
Deprecated:instead create a Promise and use Promise.complete(Object)
/** * Set the result. Any handler will be called, if there is one, and the future will be marked as completed. * * @param result the result * @deprecated instead create a {@link Promise} and use {@link Promise#complete(Object)} */
@Deprecated void complete(T result);
Set a null result. Any handler will be called, if there is one, and the future will be marked as completed.
Deprecated:instead create a Promise and use Promise.complete()
/** * Set a null result. Any handler will be called, if there is one, and the future will be marked as completed. * * @deprecated instead create a {@link Promise} and use {@link Promise#complete()} */
@Deprecated void complete();
Set the failure. Any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • cause – the failure cause
Deprecated:instead create a Promise and use Promise.fail(Throwable)
/** * Set the failure. Any handler will be called, if there is one, and the future will be marked as completed. * * @param cause the failure cause * @deprecated instead create a {@link Promise} and use {@link Promise#fail(Throwable)} */
@Deprecated void fail(Throwable cause);
Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • failureMessage – the failure message
Deprecated:instead create a Promise and use Promise.fail(String)
/** * Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed. * * @param failureMessage the failure message * @deprecated instead create a {@link Promise} and use {@link Promise#fail(String)} */
@Deprecated void fail(String failureMessage);
Set the failure. Any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • result – the result
Returns:false when the future is already completed
Deprecated:instead create a Promise and use Promise.tryComplete(Object)
/** * Set the failure. Any handler will be called, if there is one, and the future will be marked as completed. * * @param result the result * @return false when the future is already completed * @deprecated instead create a {@link Promise} and use {@link Promise#tryComplete(Object)} */
@Deprecated boolean tryComplete(T result);
Try to set the result. When it happens, any handler will be called, if there is one, and the future will be marked as completed.
Returns:false when the future is already completed
Deprecated:instead create a Promise and use Promise.tryComplete()
/** * Try to set the result. When it happens, any handler will be called, if there is one, and the future will be marked as completed. * * @return false when the future is already completed * @deprecated instead create a {@link Promise} and use {@link Promise#tryComplete()} */
@Deprecated boolean tryComplete();
Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • cause – the failure cause
Returns:false when the future is already completed
Deprecated:instead create a Promise and use Promise.tryFail(Throwable)
/** * Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed. * * @param cause the failure cause * @return false when the future is already completed * @deprecated instead create a {@link Promise} and use {@link Promise#tryFail(Throwable)} */
@Deprecated boolean tryFail(Throwable cause);
Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed.
Params:
  • failureMessage – the failure message
Returns:false when the future is already completed
Deprecated:instead create a Promise and use Promise.tryFail(String)
/** * Try to set the failure. When it happens, any handler will be called, if there is one, and the future will be marked as completed. * * @param failureMessage the failure message * @return false when the future is already completed * @deprecated instead create a {@link Promise} and use {@link Promise#tryFail(String)} */
@Deprecated boolean tryFail(String failureMessage);
The result of the operation. This will be null if the operation failed.
Returns:the result or null if the operation failed.
/** * The result of the operation. This will be null if the operation failed. * * @return the result or null if the operation failed. */
@Override T result();
A Throwable describing failure. This will be null if the operation succeeded.
Returns:the cause or null if the operation succeeded.
/** * A Throwable describing failure. This will be null if the operation succeeded. * * @return the cause or null if the operation succeeded. */
@Override Throwable cause();
Did it succeed?
Returns:true if it succeded or false otherwise
/** * Did it succeed? * * @return true if it succeded or false otherwise */
@Override boolean succeeded();
Did it fail?
Returns:true if it failed or false otherwise
/** * Did it fail? * * @return true if it failed or false otherwise */
@Override boolean failed();
Compose this future with a provided next future.

When this (the one on which compose is called) future succeeds, the handler will be called with the completed value, this handler should complete the next future.

If the handler throws an exception, the returned future will be failed with this exception.

When this future fails, the failure will be propagated to the next future and the handler will not be called.

Params:
  • handler – the handler
  • next – the next future
Returns:the next future, used for chaining
Deprecated:use compose(Function))} instead
/** * Compose this future with a provided {@code next} future.<p> * * When this (the one on which {@code compose} is called) future succeeds, the {@code handler} will be called with * the completed value, this handler should complete the next future.<p> * * If the {@code handler} throws an exception, the returned future will be failed with this exception.<p> * * When this future fails, the failure will be propagated to the {@code next} future and the {@code handler} * will not be called. * * @param handler the handler * @param next the next future * @return the next future, used for chaining * @deprecated use {@link #compose(Function)})} instead */
@GenIgnore @Deprecated default <U> Future<U> compose(Handler<T> handler, Future<U> next) { setHandler(ar -> { if (ar.succeeded()) { try { handler.handle(ar.result()); } catch (Throwable err) { if (next.isComplete()) { throw err; } next.fail(err); } } else { next.fail(ar.cause()); } }); return next; }
Compose this future with a mapper function.

When this future (the one on which compose is called) succeeds, the mapper will be called with the completed value and this mapper returns another future object. This returned future completion will complete the future returned by this method call.

If the mapper throws an exception, the returned future will be failed with this exception.

When this future fails, the failure will be propagated to the returned future and the mapper will not be called.

Params:
  • mapper – the mapper function
Returns:the composed future
/** * Compose this future with a {@code mapper} function.<p> * * When this future (the one on which {@code compose} is called) succeeds, the {@code mapper} will be called with * the completed value and this mapper returns another future object. This returned future completion will complete * the future returned by this method call.<p> * * If the {@code mapper} throws an exception, the returned future will be failed with this exception.<p> * * When this future fails, the failure will be propagated to the returned future and the {@code mapper} * will not be called. * * @param mapper the mapper function * @return the composed future */
default <U> Future<U> compose(Function<T, Future<U>> mapper) { if (mapper == null) { throw new NullPointerException(); } Promise<U> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { Future<U> apply; try { apply = mapper.apply(ar.result()); } catch (Throwable e) { ret.fail(e); return; } apply.setHandler(ret); } else { ret.fail(ar.cause()); } }); return ret.future(); }
Apply a mapper function on this future.

When this future succeeds, the mapper will be called with the completed value and this mapper returns a value. This value will complete the future returned by this method call.

If the mapper throws an exception, the returned future will be failed with this exception.

When this future fails, the failure will be propagated to the returned future and the mapper will not be called.

Params:
  • mapper – the mapper function
Returns:the mapped future
/** * Apply a {@code mapper} function on this future.<p> * * When this future succeeds, the {@code mapper} will be called with the completed value and this mapper * returns a value. This value will complete the future returned by this method call.<p> * * If the {@code mapper} throws an exception, the returned future will be failed with this exception.<p> * * When this future fails, the failure will be propagated to the returned future and the {@code mapper} * will not be called. * * @param mapper the mapper function * @return the mapped future */
default <U> Future<U> map(Function<T, U> mapper) { if (mapper == null) { throw new NullPointerException(); } Promise<U> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { U mapped; try { mapped = mapper.apply(ar.result()); } catch (Throwable e) { ret.fail(e); return; } ret.complete(mapped); } else { ret.fail(ar.cause()); } }); return ret.future(); }
Map the result of a future to a specific value.

When this future succeeds, this value will complete the future returned by this method call.

When this future fails, the failure will be propagated to the returned future.

Params:
  • value – the value that eventually completes the mapped future
Returns:the mapped future
/** * Map the result of a future to a specific {@code value}.<p> * * When this future succeeds, this {@code value} will complete the future returned by this method call.<p> * * When this future fails, the failure will be propagated to the returned future. * * @param value the value that eventually completes the mapped future * @return the mapped future */
default <V> Future<V> map(V value) { Promise<V> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { ret.complete(value); } else { ret.fail(ar.cause()); } }); return ret.future(); }
Map the result of a future to null.

This is a conveniency for future.map((T) null) or future.map((Void) null).

When this future succeeds, null will complete the future returned by this method call.

When this future fails, the failure will be propagated to the returned future.

Returns:the mapped future
/** * Map the result of a future to {@code null}.<p> * * This is a conveniency for {@code future.map((T) null)} or {@code future.map((Void) null)}.<p> * * When this future succeeds, {@code null} will complete the future returned by this method call.<p> * * When this future fails, the failure will be propagated to the returned future. * * @return the mapped future */
@Override default <V> Future<V> mapEmpty() { return (Future<V>) AsyncResult.super.mapEmpty(); }
Succeed or fail this future with the AsyncResult event.
Params:
  • asyncResult – the async result to handle
/** * Succeed or fail this future with the {@link AsyncResult} event. * * @param asyncResult the async result to handle */
@GenIgnore @Override void handle(AsyncResult<T> asyncResult);
Returns:an handler completing this future
Deprecated:use this object instead since it extends Handler<AsyncResult<T>>
/** * @return an handler completing this future * @deprecated use this object instead since it extends {@code Handler<AsyncResult<T>>} */
@Deprecated @CacheReturn default Handler<AsyncResult<T>> completer() { return this; }
Handles a failure of this Future by returning the result of another Future. If the mapper fails, then the returned future will be failed with this failure.
Params:
  • mapper – A function which takes the exception of a failure and returns a new future.
Returns:A recovered future
/** * Handles a failure of this Future by returning the result of another Future. * If the mapper fails, then the returned future will be failed with this failure. * * @param mapper A function which takes the exception of a failure and returns a new future. * @return A recovered future */
default Future<T> recover(Function<Throwable, Future<T>> mapper) { if (mapper == null) { throw new NullPointerException(); } Promise<T> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { ret.complete(result()); } else { Future<T> mapped; try { mapped = mapper.apply(ar.cause()); } catch (Throwable e) { ret.fail(e); return; } mapped.setHandler(ret); } }); return ret.future(); }
Apply a mapper function on this future.

When this future fails, the mapper will be called with the completed value and this mapper returns a value. This value will complete the future returned by this method call.

If the mapper throws an exception, the returned future will be failed with this exception.

When this future succeeds, the result will be propagated to the returned future and the mapper will not be called.

Params:
  • mapper – the mapper function
Returns:the mapped future
/** * Apply a {@code mapper} function on this future.<p> * * When this future fails, the {@code mapper} will be called with the completed value and this mapper * returns a value. This value will complete the future returned by this method call.<p> * * If the {@code mapper} throws an exception, the returned future will be failed with this exception.<p> * * When this future succeeds, the result will be propagated to the returned future and the {@code mapper} * will not be called. * * @param mapper the mapper function * @return the mapped future */
default Future<T> otherwise(Function<Throwable, T> mapper) { if (mapper == null) { throw new NullPointerException(); } Promise<T> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { ret.complete(result()); } else { T value; try { value = mapper.apply(ar.cause()); } catch (Throwable e) { ret.fail(e); return; } ret.complete(value); } }); return ret.future(); }
Map the failure of a future to a specific value.

When this future fails, this value will complete the future returned by this method call.

When this future succeeds, the result will be propagated to the returned future.

Params:
  • value – the value that eventually completes the mapped future
Returns:the mapped future
/** * Map the failure of a future to a specific {@code value}.<p> * * When this future fails, this {@code value} will complete the future returned by this method call.<p> * * When this future succeeds, the result will be propagated to the returned future. * * @param value the value that eventually completes the mapped future * @return the mapped future */
default Future<T> otherwise(T value) { Promise<T> ret = Promise.promise(); setHandler(ar -> { if (ar.succeeded()) { ret.complete(result()); } else { ret.complete(value); } }); return ret.future(); }
Map the failure of a future to null.

This is a convenience for future.otherwise((T) null).

When this future fails, the null value will complete the future returned by this method call.

When this future succeeds, the result will be propagated to the returned future.

Returns:the mapped future
/** * Map the failure of a future to {@code null}.<p> * * This is a convenience for {@code future.otherwise((T) null)}.<p> * * When this future fails, the {@code null} value will complete the future returned by this method call.<p> * * When this future succeeds, the result will be propagated to the returned future. * * @return the mapped future */
default Future<T> otherwiseEmpty() { return (Future<T>) AsyncResult.super.otherwiseEmpty(); } @GenIgnore FutureFactory factory = ServiceHelper.loadFactory(FutureFactory.class); }