Index: sdk/lib/async/future.dart |
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart |
index b7ad177dececd13c467974e832d39a8eeae0946a..6683edef8a5469536d04454436d6a209d21e941b 100644 |
--- a/sdk/lib/async/future.dart |
+++ b/sdk/lib/async/future.dart |
@@ -7,21 +7,25 @@ part of dart.async; |
/** |
* An object representing a delayed computation. |
* |
- * A [Future] is used to obtain a not yet |
- * available value, or error, sometime in the future. Receivers of a |
- * [Future] can register callbacks that handle the value or error once it is |
- * available. For example: |
+ * A [Future] is used to represent a potential value, or error, |
+ * that will be available at some time in the future. |
+ * Receivers of a [Future] can register callbacks |
+ * that handle the value or error once it is available. |
+ * For example: |
* |
* Future<int> future = getFuture(); |
* future.then((value) => handleValue(value)) |
* .catchError((error) => handleError(error)); |
* |
- * A [Future] can be completed in two ways: with a value ("the future succeeds") |
- * or with an error ("the future fails"). Users can install callbacks for each |
- * case. The result of registering a pair of callbacks is a new Future (the |
+ * A [Future] can complete in two ways: |
+ * with a value ("the future succeeds") |
+ * or with an error ("the future fails"). |
+ * Users can install callbacks for each case. |
+ * The result of registering a pair of callbacks is a new Future (the |
* "successor") which in turn is completed with the result of invoking the |
- * corresponding callback. The successor is completed with an error if the |
- * invoked callback throws. For example: |
+ * corresponding callback. |
+ * The successor is completed with an error if the invoked callback throws. |
+ * For example: |
* |
* Future<int> successor = future.then((int value) { |
* // Invoked when the future is completed with a value. |
@@ -36,31 +40,32 @@ part of dart.async; |
* } |
* }); |
* |
- * If a future does not have a successor but is completed with an error, it |
- * forwards the error message to the global error-handler. This special casing |
- * makes sure that no error is silently dropped. However, it also means that |
- * error handlers should be installed early, so that they are present as soon |
- * as a future is completed with an error. The following example demonstrates |
- * this potential bug: |
+ * If a future does not have a successor when it completes with an error, |
+ * it forwards the error message to the global error-handler. |
+ * This special case makes sure that no error is silently dropped. |
Anders Johnsen
2014/03/12 09:21:01
Behavior?
Lasse Reichstein Nielsen
2014/03/13 15:11:56
Done.
|
+ * However, it also means that error handlers should be installed early, |
+ * so that they are present as soon as a future is completed with an error. |
+ * The following example demonstrates this potential bug: |
* |
* var future = getFuture(); |
* new Timer(new Duration(milliseconds: 5), () { |
- * // The error-handler is only attached 5ms after the future has been |
- * // received. If the future fails in the mean-time it will forward the |
- * // error to the global error-handler, even though there is code (just |
- * // below) to handle the error. |
+ * // The error-handler is only attached 5 ms after the future has been |
Anders Johnsen
2014/03/12 09:21:01
Is first attached?
Or
Is not attached until 5 ms
Lasse Reichstein Nielsen
2014/03/13 15:11:56
Done.
|
+ * // received. If the future fails before that, the error is forwarded |
+ * // to the global error-handler, even though there is code (just |
+ * // below) to eventually handle the error. |
* future.then((value) { useValue(value); }, |
* onError: (e) { handleError(e); }); |
* }); |
* |
- * In general we discourage registering the two callbacks at the same time, but |
- * prefer to use [then] with one argument (the value handler), and to use |
- * [catchError] for handling errors. The missing callbacks (the error-handler |
- * for [then], and the value-handler for [catchError]), are automatically |
- * configured to "forward" the value/error. Separating value and error-handling |
- * into separate registration calls usually leads to code that is easier to |
- * reason about. In fact it makes asynchronous code very similar to synchronous |
- * code: |
+ * In general we encourage registering the two callbacks separately, |
Anders Johnsen
2014/03/12 09:21:01
IMO "we" should not be used in code docs.
Lasse Reichstein Nielsen
2014/03/13 15:11:56
Done.
|
+ * by using [then] with one argument (the value handler) and |
+ * using [catchError] for handling errors. |
+ * The omitted callbacks (the error-handler for [then], |
+ * and the value-handler for [catchError]), are automatically |
Anders Johnsen
2014/03/12 09:21:01
Value handler for catch error - do we have that?
Lasse Reichstein Nielsen
2014/03/13 15:11:56
No, which is why it's missing (and why "missing" i
|
+ * configured to forward the value/error directly to the successor. |
+ * Separating value and error-handling into separate registration calls |
+ * usually leads to code that is easier to reason about. |
+ * It also makes asynchronous code very similar to synchronous code: |
* |
* // Synchronous code. |
* try { |
@@ -72,19 +77,21 @@ part of dart.async; |
* |
* Equivalent asynchronous code, based on futures: |
* |
- * Future<int> future = foo(); // foo now returns a future. |
+ * Future<int> future = new Future(foo); // Result of foo() as a future. |
* future.then((int value) => bar(value)) |
* .catchError((e) => 499); |
* |
* Similar to the synchronous code, the error handler (registered with |
- * [catchError]) is handling the errors for exceptions coming from calls to |
- * 'foo', as well as 'bar'. This would not be the case if the error-handler was |
- * registered at the same time as the value-handler. |
+ * [catchError]) is handling any errors thrown by either `foo` or `bar`. |
+ * If the error-handler had been registered as the `onError` parameter of |
+ * the `then` call, it would not catch errors from the `bar` call. |
* |
- * Futures can have more than one callback-pairs registered. Each successor is |
+ * Futures can have more than one callback-pair registered. Each successor is |
* treated independently and is handled as if it was the only successor. |
+ * |
+ * A future may also fail to ever complete. In that case, no callbacks are |
+ * called. |
*/ |
-// TODO(floitsch): document chaining. |
abstract class Future<T> { |
// The `_nullFuture` is a completed Future with the value `null`. |
static final _Future _nullFuture = new Future.value(null); |
@@ -100,7 +107,8 @@ abstract class Future<T> { |
* the created future will wait until the returned future completes, |
* and will then complete with the same result. |
* |
- * If a value is returned, it becomes the result of the created future. |
+ * If a non-future value is returned, the returned future is completed |
+ * with that value. |
*/ |
factory Future(computation()) { |
_Future result = new _Future<T>(); |
@@ -118,14 +126,15 @@ abstract class Future<T> { |
* Creates a future containing the result of calling [computation] |
* asynchronously with [scheduleMicrotask]. |
* |
- * If the result of executing [computation] throws, the returned future is |
- * completed with the error. |
+ * If executing [computation] throws, |
+ * the returned future is completed with the thrown error. |
* |
- * If the returned value is itself a [Future], completion of |
+ * If calling [computation] returns a [Future], completion of |
* the created future will wait until the returned future completes, |
* and will then complete with the same result. |
* |
- * If a value is returned, it becomes the result of the created future. |
+ * If calling [computation] returns a non-future value, |
+ * the returned future is completed with that value. |
*/ |
factory Future.microtask(computation()) { |
_Future result = new _Future<T>(); |
@@ -146,9 +155,12 @@ abstract class Future<T> { |
* If calling [computation] throws, the returned future is completed with the |
* error. |
* |
- * If the returned value is itself a [Future], completion of |
+ * If calling [computation] returns a [Future], completion of |
* the created future will wait until the returned future completes, |
* and will then complete with the same result. |
+ * |
+ * If calling [computation] returns a non-future value, |
+ * the returned future is completed with that value. |
*/ |
factory Future.sync(computation()) { |
try { |
@@ -165,7 +177,7 @@ abstract class Future<T> { |
* If [value] is not a [Future], using this constructor is equivalent |
* to [:new Future<T>.sync(() => value):]. |
* |
- * See [Completer] to create a Future and complete it later. |
+ * Use [Completer] to create a Future and complete it later. |
*/ |
factory Future.value([value]) { |
return new _Future<T>.immediate(value); |
@@ -174,7 +186,7 @@ abstract class Future<T> { |
/** |
* A future that completes with an error in the next event-loop iteration. |
* |
- * See [Completer] to create a Future and complete it later. |
+ * Use [Completer] to create a Future and complete it later. |
*/ |
factory Future.error(Object error, [StackTrace stackTrace]) { |
return new _Future<T>.immediateError(error, stackTrace); |
@@ -187,14 +199,15 @@ abstract class Future<T> { |
* the result of calling [computation]. If the duration is 0 or less, it |
* completes no sooner than in the next event-loop iteration. |
* |
- * If [computation] is not given or [:null:] then it will behave as if |
- * [computation] was set to [:() => null:]. That is, it will complete with |
- * [:null:]. |
+ * If [computation] is omitted, |
+ * it will be treated as if [computation] was set to `() => null`, |
+ * and the future will eventually complete with the `null` value. |
* |
* If calling [computation] throws, the created future will complete with the |
* error. |
* |
- * See [Completer]s, for futures with values that are computed asynchronously. |
+ * See also [Completer] for a way to complete a future at a later |
+ * time that isn't a known fixed duration. |
*/ |
factory Future.delayed(Duration duration, [T computation()]) { |
Completer completer = new Completer.sync(); |
@@ -316,7 +329,7 @@ abstract class Future<T> { |
* the returned future is completed with the thrown error |
* and a stack trace for the error. |
* In the case of `onError`, |
- * if the exception thrown is the same as the argument to `onError`, |
+ * if the exception thrown is `identical` to the error argument to `onError`, |
* the throw is considered a rethrow, |
* and the original stack trace is used instead. |
* |
@@ -324,7 +337,8 @@ abstract class Future<T> { |
* the future returned by `then` will be completed with |
* the same result of the future returned by the callback. |
* |
- * If [onError] is not given it forwards the error to `f`. |
+ * If [onError] is not given, and this future completes with an error, |
+ * the error is forwarded directly to the returned future. |
* |
* In most cases, it is more readable to use [catchError] separately, possibly |
* with a `test` parameter, instead of handling both value and error in a |