/** * Iterates over the given input and invokes an async function for each element. * <p> * Note that this is done sequentially, therefore only one call happens at a time * * @param items the items to iterate over * @param toPromiseHandler the async function which returns a promise to indicate completion * @param resultConsumer the handler used to collect the results * @param <I> the input type * @param <O> the output type generated by the async function * @return a future which is fulfilled once all items have been processer or failed if one item fails */ public static <I, O> Future processChain(Iterable<I> items, Function<I, Promise<O>> toPromiseHandler, BiConsumer<I, O> resultConsumer) { Future result = new Future(); processChain(items.iterator(), toPromiseHandler, resultConsumer, result); return result; }
private static <I, O> void processChain(Iterator<I> iter, Function<I, Promise<O>> toPromiseHandler, BiConsumer<I, O> resultConsumer, Future completionFuture) { if (!iter.hasNext()) { completionFuture.success(); return; } I item = iter.next(); toPromiseHandler.apply(item).onSuccess(result -> { resultConsumer.accept(item, result); processChain(iter, toPromiseHandler, resultConsumer, completionFuture); }).onFailure(completionFuture::fail); }
/** * Transforms a collection of items into a promise for a list of results while invoking an async function for * each item. * * @param input the items to iterate over * @param toPromiseHandler the async function which returns a promise to indicate completion * @param <I> the input type * @param <O> the output type generated by the async function * @return a promise containing the invocation results of the async function for each item in the input */ public static <I, O> Promise<List<O>> sequence(Iterable<I> input, Function<I, Promise<O>> toPromiseHandler) { Promise<List<O>> result = new Promise<>(); List<O> buffer = new ArrayList<>(); processChain(input, toPromiseHandler, (ignored, output) -> buffer.add(output)).onSuccess(() -> result.success( buffer)).onFailure(result::fail); return result; }