blob: 4e022f5981ef483067daeecebe6626109e2b3578 [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> {
/// Like [fold], but instead of producing a single value it yields each
/// intermediate accumulation.
///
/// 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 the original.
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 as S;
}
});
}
}