Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Unified Diff: sdk/lib/async/future.dart

Issue 23926011: Rewrite Futures. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Fix bad asserts. Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/async/broadcast_stream_controller.dart ('k') | sdk/lib/async/future_impl.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/async/future.dart
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 4904415b1fec5dba46d86aec2dfbf956380516ea..ddeec59b659d85b8ab005d362b2b3886496d7636 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -100,18 +100,23 @@ 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;
+ _Future result = new _Future<T>();
+ Timer.run(() {
+ try {
+ result._complete(computation());
+ } catch (e, s) {
+ result._completeError(e, s);
+ }
+ });
+ return result;
}
/**
* Creates a future containing the result of immediately calling
* [computation].
*
- * 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
+ * If calling [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
@@ -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<T>.value(result);
} catch (error, stackTrace) {
- return new _FutureImpl<T>.immediateError(error, stackTrace);
+ return new Future<T>.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());
+ }
+ 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);
« no previous file with comments | « sdk/lib/async/broadcast_stream_controller.dart ('k') | sdk/lib/async/future_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698