android/guava/src/com/google/common/util/concurrent/FluentFuture.java
public final <T> FluentFuture<T> transformAsync(
      AsyncFunction<? super V, T> function, Executor executor) {
    return (FluentFuture<T>) Futures.transformAsync(this, function, executor);
  }
public final <T> FluentFuture<T> transformAsync(
      AsyncFunction<? super V, T> function, Executor executor) {
    return (FluentFuture<T>) Futures.transformAsync(this, function, executor);
  }
Returns a new {@code Future} whose result is asynchronously derived from the result of this
{@code Future}. If the input {@code Future} fails, the returned {@code Future} fails with the
same exception (and the function is not invoked).

<p>More precisely, the returned {@code Future} takes its result from a {@code Future} produced
by applying the given {@code AsyncFunction} to the result of the original {@code Future}.
Example usage:

<pre>{@code
FluentFuture<RowKey> rowKeyFuture = FluentFuture.from(indexService.lookUp(query));
ListenableFuture<QueryResult> queryFuture =
rowKeyFuture.transformAsync(dataService::readFuture, executor);
}</pre>

<p>When selecting an executor, note that {@code directExecutor} is dangerous in some cases. See
the discussion in the {@link #addListener} documentation. All its warnings about heavyweight
listeners are also applicable to heavyweight functions passed to this method. (Specifically,
{@code directExecutor} functions should avoid heavyweight operations inside {@code
AsyncFunction.apply}. Any heavyweight operations should occur in other threads responsible for
completing the returned {@code Future}.)

<p>The returned {@code Future} attempts to keep its cancellation state in sync with that of the
input future and that of the future returned by the chain function. That is, if the returned
{@code Future} is cancelled, it will attempt to cancel the other two, and if either of the
other two is cancelled, the returned {@code Future} will receive a callback in which it will
attempt to cancel itself.

<p>This method is similar to {@link java.util.concurrent.CompletableFuture#thenCompose} and
{@link java.util.concurrent.CompletableFuture#thenComposeAsync}. It can also serve some of the
use cases of {@link java.util.concurrent.CompletableFuture#handle} and {@link
java.util.concurrent.CompletableFuture#handleAsync} when used along with {@link #catching}.

@param function A function to transform the result of this future to the result of the output
future
@param executor Executor to run the function in.
@return A future that holds result of the function (if the input succeeded) or the original
input's failure (if not)