Chromium Code Reviews| Index: sdk/lib/async/future.dart |
| diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart |
| index 4904415b1fec5dba46d86aec2dfbf956380516ea..074f61caf7c8855dbdae2d3c88a6ca97d0221ea8 100644 |
| --- a/sdk/lib/async/future.dart |
| +++ b/sdk/lib/async/future.dart |
| @@ -100,10 +100,15 @@ abstract class Future<T> { |
| * If a value is returned, it becomes the result of the created future. |
| */ |
| factory Future(computation()) { |
| - _ThenFuture<dynamic, T> future = |
| - new _ThenFuture<dynamic, T>((_) => computation()); |
| - Timer.run(() => future._sendValue(null)); |
| - return future; |
| + Completer completer = new Completer.sync(); |
|
Lasse Reichstein Nielsen
2013/09/10 12:03:53
WHy not "new _Future()" followed by ".complete" or
floitsch
2013/09/10 17:19:14
Done.
|
| + Timer.run(() { |
| + try { |
| + completer.complete(computation()); |
| + } catch (e, s) { |
| + completer.completeError(e, s); |
| + } |
| + }); |
| + return completer.future; |
| } |
| /** |
| @@ -121,9 +126,9 @@ abstract class Future<T> { |
| factory Future.sync(computation()) { |
| try { |
| var result = computation(); |
| - return new _FutureImpl<T>().._setOrChainValue(result); |
| + return new Future.value(result); |
| } catch (error, stackTrace) { |
| - return new _FutureImpl<T>.immediateError(error, stackTrace); |
| + return new Future.error(error, stackTrace); |
| } |
| } |
| @@ -135,7 +140,9 @@ abstract class Future<T> { |
| * |
| * See [Completer] to create a Future and complete it later. |
| */ |
| - factory Future.value([T value]) => new _FutureImpl<T>.immediate(value); |
| + factory Future.value([T value]) { |
| + return new _Future<T>.immediate(value); |
| + } |
| /** |
| * A future that completes with an error in the next event-loop iteration. |
| @@ -143,7 +150,7 @@ abstract class Future<T> { |
| * See [Completer] to create a Future and complete it later. |
| */ |
| factory Future.error(var error, [Object stackTrace]) { |
| - return new _FutureImpl<T>.immediateError(error, stackTrace); |
| + return new _Future<T>.immediateError(error, stackTrace); |
| } |
| /** |
| @@ -163,13 +170,13 @@ abstract class Future<T> { |
| * See [Completer]s, for futures with values that are computed asynchronously. |
| */ |
| factory Future.delayed(Duration duration, [T computation()]) { |
| - // TODO(floitsch): no need to allocate a ThenFuture when the computation is |
| - // null. |
| - if (computation == null) computation = (() => null); |
| - _ThenFuture<dynamic, T> future = |
| - new _ThenFuture<dynamic, T>((_) => computation()); |
| - new Timer(duration, () => future._sendValue(null)); |
| - return future; |
| + Completer completer = new Completer.sync(); |
| + Future result = completer.future; |
| + if (computation != null) { |
| + result = result.then((ignored) => computation()); |
|
Lasse Reichstein Nielsen
2013/09/10 12:03:53
This throws away the type parameter.
Can we avoid
floitsch
2013/09/10 17:19:14
Not now.
We will go through the whole library and
|
| + } |
| + new Timer(duration, () { completer.complete(null); }); |
| + return result; |
| } |
| /** |
| @@ -181,7 +188,36 @@ abstract class Future<T> { |
| * of the returned future will be a list of all the values that were produced. |
| */ |
| static Future<List> wait(Iterable<Future> futures) { |
| - return new _FutureImpl<List>.wait(futures); |
| + Completer completer; |
| + // List collecting values from the futures. |
| + // Set to null if an error occurs. |
| + List values; |
| + void handleError(error) { |
| + if (values != null) { |
| + values = null; |
| + completer.completeError(error); |
| + } |
| + } |
| + // As each future completes, put its value into the corresponding |
| + // position in the list of values. |
| + int remaining = 0; |
| + for (Future future in futures) { |
| + int pos = remaining++; |
| + future.catchError(handleError).then((Object value) { |
| + if (values == null) return null; |
| + values[pos] = value; |
| + remaining--; |
| + if (remaining == 0) { |
| + completer.complete(values); |
| + } |
| + }); |
| + } |
| + if (remaining == 0) { |
| + return new Future.value(const []); |
| + } |
| + values = new List(remaining); |
| + completer = new Completer<List>(); |
| + return completer.future; |
| } |
| /** |
| @@ -195,14 +231,14 @@ abstract class Future<T> { |
| * iteration to stop and will be piped through the returned [Future]. |
| */ |
| static Future forEach(Iterable input, Future f(element)) { |
| - _FutureImpl doneSignal = new _FutureImpl(); |
| + _Future doneSignal = new _Future(); |
| Iterator iterator = input.iterator; |
| void nextElement(_) { |
| if (iterator.moveNext()) { |
| new Future.sync(() => f(iterator.current)) |
| - .then(nextElement, onError: doneSignal._setError); |
| + .then(nextElement, onError: doneSignal._completeError); |
| } else { |
| - doneSignal._setValue(null); |
| + doneSignal._complete(null); |
| } |
| } |
| nextElement(null); |