src/main/java/com/github/phantomthief/concurrent/MoreFutures.java
@Nonnull
    public static <K, V, X extends Throwable> Map<K, V> tryWait(@Nonnull Iterable<K> keys,
            @Nonnegative long timeout, @Nonnull TimeUnit unit,
            @Nonnull ThrowableFunction<K, Future<V>, X> asyncFunc)
            throws X, TryWaitUncheckedException {
        return tryWait(keys, timeout, unit, asyncFunc, TryWaitUncheckedException::new);
    }
@Nonnull
    public static <K, V, X extends Throwable> Map<K, V> tryWait(@Nonnull Iterable<K> keys,
            @Nonnegative long timeout, @Nonnull TimeUnit unit,
            @Nonnull ThrowableFunction<K, Future<V>, X> asyncFunc)
            throws X, TryWaitUncheckedException {
        return tryWait(keys, timeout, unit, asyncFunc, TryWaitUncheckedException::new);
    }
A typical usage:
{@code <pre>
// a fail-safe example
List<Integer> list = getSomeIds();
Map<Integer, User> success;
try {
success = tryWait(list, 1, SECONDS, id -> executor.submit(() -> retrieve(id)));
} catch (TryWaitUncheckedException e) {
success = e.getSuccess(); // there are still some success
}

// a fail-fast example
List<Integer> list = getSomeIds();
// don't try/catch the exception it throws.
Map<Integer, User> success = tryWait(list, 1, SECONDS, id -> executor.submit(() -> retrieve(id)));
</pre>}

@throws TryWaitUncheckedException if not all calls are successful.