blob: acd3c76762415d1cb5e0a18369cc69f8b3f9968b [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
/// A utility similar to [fold] which emits intermediate accumulations.
extension Scan<T> on Stream<T> {
/// Emits a sequence of the accumulated values from repeatedly applying
/// [combine].
///
/// Like [fold], but instead of producing a single value it yields each
/// intermediate result.
///
/// If [combine] returns a future it will not be called again for subsequent
/// events from the source until it completes, therefore [combine] is always
/// called for elements in order, and the result stream always maintains the
/// same order as this stream.
Stream<S> scan<S>(
S initialValue, FutureOr<S> Function(S soFar, T element) combine) {
var accumulated = initialValue;
return asyncMap((value) {
var result = combine(accumulated, value);
if (result is Future<S>) {
return result.then((r) => accumulated = r);
} else {
return accumulated = result;
}
});
}
}