reduce 方法

Future<T> reduce(
  1. T combine(
    1. T previous,
    2. T element
    )
)

通过反复应用 combine 结合一个序列的值。

类似于 Iterable.reduce,此函数维护一个值,从此流的第一个元素开始,并为此流的每个后续元素更新。对于第一个元素之后的每个元素,值更新为使用上一个值和元素调用 combine 的结果。

当此流完成时,返回的 future 将完成该时的值。

如果此流为空,返回的 future 将以错误完成。如果此流发出错误,或 combine 的调用抛出异常,返回的 future 将以该错误完成,并且处理将停止。

示例

final result = await Stream.fromIterable([2, 6, 10, 8, 2])
    .reduce((previous, element) => previous + element);
print(result); // 28

实现

Future<T> reduce(T combine(T previous, T element)) {
  _Future<T> result = new _Future<T>();
  bool seenFirst = false;
  late T value;
  StreamSubscription<T> subscription =
      this.listen(null, onError: result._completeError, 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 IterableElementError.noElement();
      } catch (e, s) {
        _completeWithErrorCallback(result, e, s);
      }
    } else {
      result._complete(value);
    }
  }, cancelOnError: true);
  subscription.onData((T element) {
    if (seenFirst) {
      _runUserCode(() => combine(value, element), (T newValue) {
        value = newValue;
      }, _cancelAndErrorClosure(subscription, result));
    } else {
      value = element;
      seenFirst = true;
    }
  });
  return result;
}