Future <string> join(string separator = "") { _Future result = new _Future(); StringBuilder buffer = new StringBuilder(); StreamSubscription <T> subscription = null; bool first = true; subscription = listen( (T element) => { if (!first) { buffer.Append(separator); } first = false; try { buffer.Append(element); } catch (Exception e) { _stream._cancelAndErrorWithReplacement(subscription, result, e); } }, onError: (e, _) => result._completeError((Exception)e), onDone: () => { result._complete(buffer.ToString()); }, cancelOnError: true); return(result.to <string>()); }
Future <S> fold <S>(S initialValue, Func <S, T, S> combine) { _Future result = new _Future(); S value = initialValue; StreamSubscription <T> subscription = null; subscription = listen( (T element) => { _stream._runUserCode(() => combine(value, element), (S newValue) => { value = newValue; }, e => _stream._cancelAndErrorClosure(subscription, result)(e)); }, onError: (e, s) => result._completeError((Exception)e), onDone: () => { result._complete(FutureOr.value(value)); }, cancelOnError: true); return(result.to <S>()); }
Future <bool> contains(object needle) { _Future future = new _Future(); StreamSubscription <T> subscription = null; subscription = listen( (T element) => { _stream._runUserCode(() => (Equals(element, needle)), (bool isMatch) => { if (isMatch) { _stream._cancelAndValue(subscription, future, true); } }, (e) => _stream._cancelAndErrorClosure(subscription, future)(e)); }, onError: (e, _) => future._completeError((Exception)e), onDone: () => { future._complete(false); }, cancelOnError: true); return(future.to <bool>()); }
Future <T> reduce(Func <T, T, T> combine) { _Future result = new _Future(); bool seenFirst = false; T value = default; StreamSubscription <T> subscription = null; subscription = listen( (T element) => { if (seenFirst) { _stream._runUserCode(() => combine(value, element), (T newValue) => { value = newValue; }, onError: (e) => _stream._cancelAndErrorClosure(subscription, result)(e)); } else { value = element; seenFirst = true; } }, onError: (e, s) => result._completeError((Exception)e), onDone: () => { if (!seenFirst) { try { // Throw and recatch, instead of just doing // _completeWithErrorCallback, e, theError, StackTrace.current), // to ensure that the stackTrace is set on the error. throw new Exception("IterableElementError.noElement()"); } catch (Exception e) { async_._completeWithErrorCallback(result, e); } } else { // TODO: need check result._complete(FutureOr.value(value)); } }, cancelOnError: true); return(result.to <T>()); }