Index: utils/pub/utils.dart |
diff --git a/utils/pub/utils.dart b/utils/pub/utils.dart |
index 4311c0946e59e13fb89b344e2b7158f95e7bde33..d18bb4e31ca915d82a5e125d5e13de4c8b6f03c3 100644 |
--- a/utils/pub/utils.dart |
+++ b/utils/pub/utils.dart |
@@ -27,6 +27,47 @@ class Pair<E, F> { |
int get hashCode => first.hashCode ^ last.hashCode; |
} |
+/// A completer that waits until all added [Future]s complete. |
+// TODO(rnystrom): Copied from web_components. Remove from here when it gets |
+// added to dart:core. (See #6626.) |
+class FutureGroup<T> { |
+ int _pending = 0; |
+ Completer<List<T>> _completer = new Completer<List<T>>(); |
+ final List<Future<T>> futures = <Future<T>>[]; |
+ bool completed = false; |
+ |
+ final List<T> _values = <T>[]; |
+ |
+ /// Wait for [task] to complete. |
+ Future<T> add(Future<T> task) { |
+ if (completed) { |
+ throw new StateError("The FutureGroup has already completed."); |
+ } |
+ |
+ _pending++; |
+ futures.add(task.then((value) { |
+ if (completed) return; |
+ |
+ _pending--; |
+ _values.add(value); |
+ |
+ if (_pending <= 0) { |
+ completed = true; |
+ _completer.complete(_values); |
+ } |
+ }).catchError((e) { |
+ if (completed) return; |
+ |
+ completed = true; |
+ _completer.completeError(e.error, e.stackTrace); |
+ })); |
+ |
+ return task; |
+ } |
+ |
+ Future<List> get future => _completer.future; |
+} |
+ |
// TODO(rnystrom): Move into String? |
/// Pads [source] to [length] by adding spaces at the end. |
String padRight(String source, int length) { |