/** Causes {@code slot} to be notified if/when this future is completed with failure. If it has * already failed, the slot will be notified immediately. * @return this future for chaining. */ public RFuture<T> onFailure (final SignalView.Listener<? super Throwable> slot) { return onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) slot.onEmit(result.getFailure()); } }); }
/** Causes {@code slot} to be notified if/when this future is completed with success. If it has * already succeeded, the slot will be notified immediately. * @return this future for chaining. */ public RFuture<T> onSuccess (final SignalView.Listener<? super T> slot) { return onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isSuccess()) slot.onEmit(result.get()); } }); }
/** Causes {@code slot} to be notified if/when this future is completed with failure. If it has * already failed, the slot will be notified immediately. * @return this future for chaining. */ public RFuture<T> onFailure (final SignalView.Listener<? super Throwable> slot) { return onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) slot.onEmit(result.getFailure()); } }); }
/** Causes {@code slot} to be notified if/when this future is completed with success. If it has * already succeeded, the slot will be notified immediately. * @return this future for chaining. */ public RFuture<T> onSuccess (final SignalView.Listener<? super T> slot) { return onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isSuccess()) slot.onEmit(result.get()); } }); }
/** Returns a value that indicates whether this future has completed. */ public ValueView<Boolean> isComplete () { if (_isCompleteView == null) { final Value<Boolean> isCompleteView = Value.create(false); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { isCompleteView.update(true); } }); _isCompleteView = isCompleteView; } return _isCompleteView; }
/** Returns a value that indicates whether this future has completed. */ public ValueView<Boolean> isComplete () { if (_isCompleteView == null) { final Value<Boolean> isCompleteView = Value.create(false); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { isCompleteView.update(true); } }); _isCompleteView = isCompleteView; } return _isCompleteView; }
/** Transforms this future by mapping its result upon arrival. */ public <R> RFuture<R> transform (final Function<Try<? super T>,Try<R>> func) { final RPromise<R> xf = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { Try<R> xfResult; try { xfResult = func.apply(result); } catch (Throwable t) { xf.fail(t); return; } xf.complete(xfResult); } }); return xf; }
/** Transforms this future by mapping its result upon arrival. */ public <R> RFuture<R> transform (final Function<Try<? super T>,Try<R>> func) { final RPromise<R> xf = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { Try<R> xfResult; try { xfResult = func.apply(result); } catch (Throwable t) { xf.fail(t); return; } xf.complete(xfResult); } }); return xf; }
/** Maps a successful result to a new result using {@code func} when it arrives. Failure on the * original result or the mapped result are both dispatched to the mapped result. This is * useful for chaining asynchronous actions. It's also known as monadic bind. */ public <R> RFuture<R> flatMap (final Function<? super T, RFuture<R>> func) { final RPromise<R> mapped = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) mapped.fail(result.getFailure()); else { RFuture<R> mappedResult; try { mappedResult = func.apply(result.get()); } catch (Throwable t) { mapped.fail(t); return; } mappedResult.onComplete(mapped.completer()); } } }); return mapped; }
/** Maps a successful result to a new result using {@code func} when it arrives. Failure on the * original result or the mapped result are both dispatched to the mapped result. This is * useful for chaining asynchronous actions. It's also known as monadic bind. */ public <R> RFuture<R> flatMap (final Function<? super T, RFuture<R>> func) { final RPromise<R> mapped = RPromise.create(); onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { if (result.isFailure()) mapped.fail(result.getFailure()); else { RFuture<R> mappedResult; try { mappedResult = func.apply(result.get()); } catch (Throwable t) { mapped.fail(t); return; } mappedResult.onComplete(mapped.completer()); } } }); return mapped; }
/** Returns a future containing a list of all success results from {@code futures}. Any failure * results are simply omitted from the list. The success results are also in no particular * order. If all of {@code futures} fail, the resulting list will be empty. */ public static <T> RFuture<Collection<T>> collect (Collection<? extends RFuture<T>> futures) { // if we're passed an empty list of futures, succeed immediately with an empty list if (futures.isEmpty()) return RFuture.<Collection<T>>success(Collections.<T>emptyList()); final RPromise<Collection<T>> pseq = RPromise.create(); final int count = futures.size(); SignalView.Listener<Try<T>> collector = new SignalView.Listener<Try<T>>() { public synchronized void onEmit (Try<T> result) { if (result.isSuccess()) _results.add(result.get()); if (--_remain == 0) pseq.succeed(_results); } protected final List<T> _results = new ArrayList<T>(); protected int _remain = count; }; for (RFuture<T> future : futures) future.onComplete(collector); return pseq; }
/** Returns a future containing a list of all success results from {@code futures}. Any failure * results are simply omitted from the list. The success results are also in no particular * order. If all of {@code futures} fail, the resulting list will be empty. */ public static <T> RFuture<Collection<T>> collect (Collection<? extends RFuture<T>> futures) { // if we're passed an empty list of futures, succeed immediately with an empty list if (futures.isEmpty()) return RFuture.<Collection<T>>success(Collections.<T>emptyList()); final RPromise<Collection<T>> pseq = RPromise.create(); final int count = futures.size(); SignalView.Listener<Try<T>> collector = new SignalView.Listener<Try<T>>() { public synchronized void onEmit (Try<T> result) { if (result.isSuccess()) _results.add(result.get()); if (--_remain == 0) pseq.succeed(_results); } protected final List<T> _results = new ArrayList<T>(); protected int _remain = count; }; for (RFuture<T> future : futures) future.onComplete(collector); return pseq; }
for (int ii = 0; iter.hasNext(); ii++) { final int idx = ii; iter.next().onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { seq.onResult(idx, result); } });
for (int ii = 0; iter.hasNext(); ii++) { final int idx = ii; iter.next().onComplete(new SignalView.Listener<Try<T>>() { public void onEmit (Try<T> result) { seq.onResult(idx, result); } });