@Nonnull
    default <U> Promise<U> thenCompose(@Nonnull ThreadContext context, @Nonnull Function<? super V, ? extends Promise<U>> fn) {
        switch (context) {
            case SYNC:
                return thenComposeSync(fn);
            case ASYNC:
                return thenComposeAsync(fn);
            default:
                throw new AssertionError();
        }
    }
Returns a new Promise that, when this promise completes normally, is
executed with this promise's result as the argument to the given
function.

@param context the type of executor to use to supply the promise
@param fn the function to use to compute the value
@param <U> the result type
@return the new promise
helper/src/main/java/me/lucko/helper/promise/Promise.java