Chromium Code Reviews| Index: sdk/lib/async/future.dart |
| diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart |
| index f88305b564fa179821823393f9942b95057f7ed2..f5328b49cc7197393e38c910ce22f844c0384b14 100644 |
| --- a/sdk/lib/async/future.dart |
| +++ b/sdk/lib/async/future.dart |
| @@ -291,19 +291,43 @@ abstract class Future<T> { |
| * |
| * The return values of all [Future]s are discarded. Any errors will cause the |
| * iteration to stop and will be piped through the returned [Future]. |
| + * |
| + * [f] may return a [Future] or a non-[Future] value. |
|
Lasse Reichstein Nielsen
2014/06/26 06:26:49
Add "The function " first, to not begin the senten
nweiz
2014/06/26 19:48:11
Done.
|
| */ |
| - static Future forEach(Iterable input, Future f(element)) { |
| - _Future doneSignal = new _Future(); |
| + static Future forEach(Iterable input, f(element)) { |
| Iterator iterator = input.iterator; |
| - void nextElement(_) { |
| - if (iterator.moveNext()) { |
| - new Future.sync(() => f(iterator.current)) |
| - .then(nextElement, onError: doneSignal._completeError); |
| + return doWhile(() { |
| + if (!iterator.moveNext()) return false; |
| + return new Future.sync(() => f(iterator.current)).then((_) => true); |
|
Lasse Reichstein Nielsen
2014/06/26 06:26:49
Maybe:
return new Future.sync(() { f(iterator.cu
nweiz
2014/06/26 19:48:11
That doesn't handle the case where f returns a Fut
|
| + }); |
| + } |
| + |
| + /** |
| + * Perform an async operation repeatedly until it returns `false`. |
| + * |
| + * Runs [f] repeatedly, starting the next iteration only when the [Future] |
| + * returned by [f] completes to `true`. Returns a [Future] that completes once |
| + * [f] returns `false`. |
| + * |
| + * The return values of all [Future]s are discarded. Any errors will cause the |
| + * iteration to stop and will be piped through the returned [Future]. |
| + * |
| + * [f] may return a [Future<bool>] or a non-[Future] [bool]. |
|
Lasse Reichstein Nielsen
2014/06/26 06:26:49
It can return Future<dynamic> or Future<Object> as
nweiz
2014/06/26 19:48:11
Done.
|
| + */ |
| + static Future doWhile(f()) { |
| + _Future doneSignal = new _Future(); |
| + var nextIteration; |
| + // Bind this callback explicitly so that each iteration isn't bound in the |
| + // context of all the previous iterations' callbacks. |
| + nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) { |
| + if (keepGoing) { |
| + new Future.sync(f).then(nextIteration, |
| + onError: doneSignal._completeError); |
|
Lasse Reichstein Nielsen
2014/06/26 06:26:49
Maybe indent this line to the '('?
nweiz
2014/06/26 19:48:11
Done.
|
| } else { |
| doneSignal._complete(null); |
| } |
| - } |
| - nextElement(null); |
| + }, runGuarded: true); |
| + nextIteration(keepGoing); |
|
Lasse Reichstein Nielsen
2014/06/26 06:26:49
keepGoing -> true ?
Tests? :)
nweiz
2014/06/26 19:48:11
Done.
|
| return doneSignal; |
| } |