| Index: sdk/lib/async/future.dart
|
| diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
|
| index ddeec59b659d85b8ab005d362b2b3886496d7636..4904415b1fec5dba46d86aec2dfbf956380516ea 100644
|
| --- a/sdk/lib/async/future.dart
|
| +++ b/sdk/lib/async/future.dart
|
| @@ -100,23 +100,18 @@ abstract class Future<T> {
|
| * If a value is returned, it becomes the result of the created future.
|
| */
|
| factory Future(computation()) {
|
| - _Future result = new _Future<T>();
|
| - Timer.run(() {
|
| - try {
|
| - result._complete(computation());
|
| - } catch (e, s) {
|
| - result._completeError(e, s);
|
| - }
|
| - });
|
| - return result;
|
| + _ThenFuture<dynamic, T> future =
|
| + new _ThenFuture<dynamic, T>((_) => computation());
|
| + Timer.run(() => future._sendValue(null));
|
| + return future;
|
| }
|
|
|
| /**
|
| * Creates a future containing the result of immediately calling
|
| * [computation].
|
| *
|
| - * If calling [computation] throws, the returned future is completed with the
|
| - * error. If a thrown value is an [AsyncError], it is used
|
| + * if the result of executing [computation] throws, the returned future is
|
| + * completed with the error. If a thrown value is an [AsyncError], it is used
|
| * directly, instead of wrapping this error again in another [AsyncError].
|
| *
|
| * If the returned value is itself a [Future], completion of
|
| @@ -126,9 +121,9 @@ abstract class Future<T> {
|
| factory Future.sync(computation()) {
|
| try {
|
| var result = computation();
|
| - return new Future<T>.value(result);
|
| + return new _FutureImpl<T>().._setOrChainValue(result);
|
| } catch (error, stackTrace) {
|
| - return new Future<T>.error(error, stackTrace);
|
| + return new _FutureImpl<T>.immediateError(error, stackTrace);
|
| }
|
| }
|
|
|
| @@ -140,9 +135,7 @@ abstract class Future<T> {
|
| *
|
| * See [Completer] to create a Future and complete it later.
|
| */
|
| - factory Future.value([T value]) {
|
| - return new _Future<T>.immediate(value);
|
| - }
|
| + factory Future.value([T value]) => new _FutureImpl<T>.immediate(value);
|
|
|
| /**
|
| * A future that completes with an error in the next event-loop iteration.
|
| @@ -150,7 +143,7 @@ abstract class Future<T> {
|
| * See [Completer] to create a Future and complete it later.
|
| */
|
| factory Future.error(var error, [Object stackTrace]) {
|
| - return new _Future<T>.immediateError(error, stackTrace);
|
| + return new _FutureImpl<T>.immediateError(error, stackTrace);
|
| }
|
|
|
| /**
|
| @@ -170,13 +163,13 @@ abstract class Future<T> {
|
| * See [Completer]s, for futures with values that are computed asynchronously.
|
| */
|
| factory Future.delayed(Duration duration, [T computation()]) {
|
| - Completer completer = new Completer.sync();
|
| - Future result = completer.future;
|
| - if (computation != null) {
|
| - result = result.then((ignored) => computation());
|
| - }
|
| - new Timer(duration, () { completer.complete(null); });
|
| - return result;
|
| + // 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;
|
| }
|
|
|
| /**
|
| @@ -188,36 +181,7 @@ 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) {
|
| - 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;
|
| + return new _FutureImpl<List>.wait(futures);
|
| }
|
|
|
| /**
|
| @@ -231,14 +195,14 @@ abstract class Future<T> {
|
| * iteration to stop and will be piped through the returned [Future].
|
| */
|
| static Future forEach(Iterable input, Future f(element)) {
|
| - _Future doneSignal = new _Future();
|
| + _FutureImpl doneSignal = new _FutureImpl();
|
| Iterator iterator = input.iterator;
|
| void nextElement(_) {
|
| if (iterator.moveNext()) {
|
| new Future.sync(() => f(iterator.current))
|
| - .then(nextElement, onError: doneSignal._completeError);
|
| + .then(nextElement, onError: doneSignal._setError);
|
| } else {
|
| - doneSignal._complete(null);
|
| + doneSignal._setValue(null);
|
| }
|
| }
|
| nextElement(null);
|
|
|