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

Side by Side Diff: sdk/lib/async/future.dart

Issue 195203002: Fix various documentation issues. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Addressed comments. Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/convert/json.dart » ('j') | sdk/lib/convert/json.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.async; 5 part of dart.async;
6 6
7 /** 7 /**
8 * An object representing a delayed computation. 8 * An object representing a delayed computation.
9 * 9 *
10 * A [Future] is used to obtain a not yet 10 * A [Future] is used to represent a potential value, or error,
11 * available value, or error, sometime in the future. Receivers of a 11 * that will be available at some time in the future.
12 * [Future] can register callbacks that handle the value or error once it is 12 * Receivers of a [Future] can register callbacks
13 * available. For example: 13 * that handle the value or error once it is available.
14 * For example:
14 * 15 *
15 * Future<int> future = getFuture(); 16 * Future<int> future = getFuture();
16 * future.then((value) => handleValue(value)) 17 * future.then((value) => handleValue(value))
17 * .catchError((error) => handleError(error)); 18 * .catchError((error) => handleError(error));
18 * 19 *
19 * A [Future] can be completed in two ways: with a value ("the future succeeds") 20 * A [Future] can complete in two ways:
20 * or with an error ("the future fails"). Users can install callbacks for each 21 * with a value ("the future succeeds")
21 * case. The result of registering a pair of callbacks is a new Future (the 22 * or with an error ("the future fails").
23 * Users can install callbacks for each case.
24 * The result of registering a pair of callbacks is a new Future (the
22 * "successor") which in turn is completed with the result of invoking the 25 * "successor") which in turn is completed with the result of invoking the
23 * corresponding callback. The successor is completed with an error if the 26 * corresponding callback.
24 * invoked callback throws. For example: 27 * The successor is completed with an error if the invoked callback throws.
28 * For example:
25 * 29 *
26 * Future<int> successor = future.then((int value) { 30 * Future<int> successor = future.then((int value) {
27 * // Invoked when the future is completed with a value. 31 * // Invoked when the future is completed with a value.
28 * return 42; // The successor is completed with the value 42. 32 * return 42; // The successor is completed with the value 42.
29 * }, 33 * },
30 * onError: (e) { 34 * onError: (e) {
31 * // Invoked when the future is completed with an error. 35 * // Invoked when the future is completed with an error.
32 * if (canHandle(e)) { 36 * if (canHandle(e)) {
33 * return 499; // The successor is completed with the value 499. 37 * return 499; // The successor is completed with the value 499.
34 * } else { 38 * } else {
35 * throw e; // The successor is completed with the error e. 39 * throw e; // The successor is completed with the error e.
36 * } 40 * }
37 * }); 41 * });
38 * 42 *
39 * If a future does not have a successor but is completed with an error, it 43 * If a future does not have a successor when it completes with an error,
40 * forwards the error message to the global error-handler. This special casing 44 * it forwards the error message to the global error-handler.
41 * makes sure that no error is silently dropped. However, it also means that 45 * This behavior makes sure that no error is silently dropped.
42 * error handlers should be installed early, so that they are present as soon 46 * However, it also means that error handlers should be installed early,
43 * as a future is completed with an error. The following example demonstrates 47 * so that they are present as soon as a future is completed with an error.
44 * this potential bug: 48 * The following example demonstrates this potential bug:
45 * 49 *
46 * var future = getFuture(); 50 * var future = getFuture();
47 * new Timer(new Duration(milliseconds: 5), () { 51 * new Timer(new Duration(milliseconds: 5), () {
48 * // The error-handler is only attached 5ms after the future has been 52 * // The error-handler is not attached until 5 ms after the future has
49 * // received. If the future fails in the mean-time it will forward the 53 * // been received. If the future fails before that, the error is
50 * // error to the global error-handler, even though there is code (just 54 * // forwarded to the global error-handler, even though there is code
51 * // below) to handle the error. 55 * // (just below) to eventually handle the error.
52 * future.then((value) { useValue(value); }, 56 * future.then((value) { useValue(value); },
53 * onError: (e) { handleError(e); }); 57 * onError: (e) { handleError(e); });
54 * }); 58 * });
55 * 59 *
56 * In general we discourage registering the two callbacks at the same time, but 60 * When registering callbacks, it's often more readable to register the two
57 * prefer to use [then] with one argument (the value handler), and to use 61 * callbacks separately, by first using [then] with one argument
58 * [catchError] for handling errors. The missing callbacks (the error-handler 62 * (the value handler) and using a second [catchError] for handling errors.
59 * for [then], and the value-handler for [catchError]), are automatically 63 * Each of these will forward the result that they don't handle
60 * configured to "forward" the value/error. Separating value and error-handling 64 * to their successors, and together they handle both value and error result.
61 * into separate registration calls usually leads to code that is easier to 65 * It also has the additional benefit of the [catchError] handling errors in the
62 * reason about. In fact it makes asynchronous code very similar to synchronous 66 * [then] value callback too.
63 * code: 67 * Using sequential handlers instead of parallel ones often leads to code that
68 * is easier to reason about.
69 * It also makes asynchronous code very similar to synchronous code:
64 * 70 *
65 * // Synchronous code. 71 * // Synchronous code.
66 * try { 72 * try {
67 * int value = foo(); 73 * int value = foo();
68 * return bar(value); 74 * return bar(value);
69 * } catch (e) { 75 * } catch (e) {
70 * return 499; 76 * return 499;
71 * } 77 * }
72 * 78 *
73 * Equivalent asynchronous code, based on futures: 79 * Equivalent asynchronous code, based on futures:
74 * 80 *
75 * Future<int> future = foo(); // foo now returns a future. 81 * Future<int> future = new Future(foo); // Result of foo() as a future.
76 * future.then((int value) => bar(value)) 82 * future.then((int value) => bar(value))
77 * .catchError((e) => 499); 83 * .catchError((e) => 499);
78 * 84 *
79 * Similar to the synchronous code, the error handler (registered with 85 * Similar to the synchronous code, the error handler (registered with
80 * [catchError]) is handling the errors for exceptions coming from calls to 86 * [catchError]) is handling any errors thrown by either `foo` or `bar`.
81 * 'foo', as well as 'bar'. This would not be the case if the error-handler was 87 * If the error-handler had been registered as the `onError` parameter of
82 * registered at the same time as the value-handler. 88 * the `then` call, it would not catch errors from the `bar` call.
83 * 89 *
84 * Futures can have more than one callback-pairs registered. Each successor is 90 * Futures can have more than one callback-pair registered. Each successor is
85 * treated independently and is handled as if it was the only successor. 91 * treated independently and is handled as if it was the only successor.
92 *
93 * A future may also fail to ever complete. In that case, no callbacks are
94 * called.
86 */ 95 */
87 // TODO(floitsch): document chaining.
88 abstract class Future<T> { 96 abstract class Future<T> {
89 // The `_nullFuture` is a completed Future with the value `null`. 97 // The `_nullFuture` is a completed Future with the value `null`.
90 static final _Future _nullFuture = new Future.value(null); 98 static final _Future _nullFuture = new Future.value(null);
91 99
92 /** 100 /**
93 * Creates a future containing the result of calling [computation] 101 * Creates a future containing the result of calling [computation]
94 * asynchronously with [Timer.run]. 102 * asynchronously with [Timer.run].
95 * 103 *
96 * If the result of executing [computation] throws, the returned future is 104 * If the result of executing [computation] throws, the returned future is
97 * completed with the error. 105 * completed with the error.
98 * 106 *
99 * If the returned value is itself a [Future], completion of 107 * If the returned value is itself a [Future], completion of
100 * the created future will wait until the returned future completes, 108 * the created future will wait until the returned future completes,
101 * and will then complete with the same result. 109 * and will then complete with the same result.
102 * 110 *
103 * If a value is returned, it becomes the result of the created future. 111 * If a non-future value is returned, the returned future is completed
112 * with that value.
104 */ 113 */
105 factory Future(computation()) { 114 factory Future(computation()) {
106 _Future result = new _Future<T>(); 115 _Future result = new _Future<T>();
107 Timer.run(() { 116 Timer.run(() {
108 try { 117 try {
109 result._complete(computation()); 118 result._complete(computation());
110 } catch (e, s) { 119 } catch (e, s) {
111 result._completeError(e, s); 120 result._completeError(e, s);
112 } 121 }
113 }); 122 });
114 return result; 123 return result;
115 } 124 }
116 125
117 /** 126 /**
118 * Creates a future containing the result of calling [computation] 127 * Creates a future containing the result of calling [computation]
119 * asynchronously with [scheduleMicrotask]. 128 * asynchronously with [scheduleMicrotask].
120 * 129 *
121 * If the result of executing [computation] throws, the returned future is 130 * If executing [computation] throws,
122 * completed with the error. 131 * the returned future is completed with the thrown error.
123 * 132 *
124 * If the returned value is itself a [Future], completion of 133 * If calling [computation] returns a [Future], completion of
125 * the created future will wait until the returned future completes, 134 * the created future will wait until the returned future completes,
126 * and will then complete with the same result. 135 * and will then complete with the same result.
127 * 136 *
128 * If a value is returned, it becomes the result of the created future. 137 * If calling [computation] returns a non-future value,
138 * the returned future is completed with that value.
129 */ 139 */
130 factory Future.microtask(computation()) { 140 factory Future.microtask(computation()) {
131 _Future result = new _Future<T>(); 141 _Future result = new _Future<T>();
132 scheduleMicrotask(() { 142 scheduleMicrotask(() {
133 try { 143 try {
134 result._complete(computation()); 144 result._complete(computation());
135 } catch (e, s) { 145 } catch (e, s) {
136 result._completeError(e, s); 146 result._completeError(e, s);
137 } 147 }
138 }); 148 });
139 return result; 149 return result;
140 } 150 }
141 151
142 /** 152 /**
143 * Creates a future containing the result of immediately calling 153 * Creates a future containing the result of immediately calling
144 * [computation]. 154 * [computation].
145 * 155 *
146 * If calling [computation] throws, the returned future is completed with the 156 * If calling [computation] throws, the returned future is completed with the
147 * error. 157 * error.
148 * 158 *
149 * If the returned value is itself a [Future], completion of 159 * If calling [computation] returns a [Future], completion of
150 * the created future will wait until the returned future completes, 160 * the created future will wait until the returned future completes,
151 * and will then complete with the same result. 161 * and will then complete with the same result.
162 *
163 * If calling [computation] returns a non-future value,
164 * the returned future is completed with that value.
152 */ 165 */
153 factory Future.sync(computation()) { 166 factory Future.sync(computation()) {
154 try { 167 try {
155 var result = computation(); 168 var result = computation();
156 return new Future<T>.value(result); 169 return new Future<T>.value(result);
157 } catch (error, stackTrace) { 170 } catch (error, stackTrace) {
158 return new Future<T>.error(error, stackTrace); 171 return new Future<T>.error(error, stackTrace);
159 } 172 }
160 } 173 }
161 174
162 /** 175 /**
163 * A future whose value is available in the next event-loop iteration. 176 * A future whose value is available in the next event-loop iteration.
164 * 177 *
165 * If [value] is not a [Future], using this constructor is equivalent 178 * If [value] is not a [Future], using this constructor is equivalent
166 * to [:new Future<T>.sync(() => value):]. 179 * to [:new Future<T>.sync(() => value):].
167 * 180 *
168 * See [Completer] to create a Future and complete it later. 181 * Use [Completer] to create a Future and complete it later.
169 */ 182 */
170 factory Future.value([value]) { 183 factory Future.value([value]) {
171 return new _Future<T>.immediate(value); 184 return new _Future<T>.immediate(value);
172 } 185 }
173 186
174 /** 187 /**
175 * A future that completes with an error in the next event-loop iteration. 188 * A future that completes with an error in the next event-loop iteration.
176 * 189 *
177 * See [Completer] to create a Future and complete it later. 190 * Use [Completer] to create a Future and complete it later.
178 */ 191 */
179 factory Future.error(Object error, [StackTrace stackTrace]) { 192 factory Future.error(Object error, [StackTrace stackTrace]) {
180 return new _Future<T>.immediateError(error, stackTrace); 193 return new _Future<T>.immediateError(error, stackTrace);
181 } 194 }
182 195
183 /** 196 /**
184 * Creates a future that completes after a delay. 197 * Creates a future that completes after a delay.
185 * 198 *
186 * The future will be completed after the given [duration] has passed with 199 * The future will be completed after the given [duration] has passed with
187 * the result of calling [computation]. If the duration is 0 or less, it 200 * the result of calling [computation]. If the duration is 0 or less, it
188 * completes no sooner than in the next event-loop iteration. 201 * completes no sooner than in the next event-loop iteration.
189 * 202 *
190 * If [computation] is not given or [:null:] then it will behave as if 203 * If [computation] is omitted,
191 * [computation] was set to [:() => null:]. That is, it will complete with 204 * it will be treated as if [computation] was set to `() => null`,
192 * [:null:]. 205 * and the future will eventually complete with the `null` value.
193 * 206 *
194 * If calling [computation] throws, the created future will complete with the 207 * If calling [computation] throws, the created future will complete with the
195 * error. 208 * error.
196 * 209 *
197 * See [Completer]s, for futures with values that are computed asynchronously. 210 * See also [Completer] for a way to complete a future at a later
211 * time that isn't a known fixed duration.
198 */ 212 */
199 factory Future.delayed(Duration duration, [T computation()]) { 213 factory Future.delayed(Duration duration, [T computation()]) {
200 Completer completer = new Completer.sync(); 214 Completer completer = new Completer.sync();
201 Future result = completer.future; 215 Future result = completer.future;
202 if (computation != null) { 216 if (computation != null) {
203 result = result.then((ignored) => computation()); 217 result = result.then((ignored) => computation());
204 } 218 }
205 new Timer(duration, () { completer.complete(null); }); 219 new Timer(duration, () { completer.complete(null); });
206 return result; 220 return result;
207 } 221 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 * 323 *
310 * Returns a new [Future] 324 * Returns a new [Future]
311 * which is completed with the result of the call to `onValue` 325 * which is completed with the result of the call to `onValue`
312 * (if this future completes with a value) 326 * (if this future completes with a value)
313 * or to `onError` (if this future completes with an error). 327 * or to `onError` (if this future completes with an error).
314 * 328 *
315 * If the invoked callback throws, 329 * If the invoked callback throws,
316 * the returned future is completed with the thrown error 330 * the returned future is completed with the thrown error
317 * and a stack trace for the error. 331 * and a stack trace for the error.
318 * In the case of `onError`, 332 * In the case of `onError`,
319 * if the exception thrown is the same as the argument to `onError`, 333 * if the exception thrown is `identical` to the error argument to `onError`,
320 * the throw is considered a rethrow, 334 * the throw is considered a rethrow,
321 * and the original stack trace is used instead. 335 * and the original stack trace is used instead.
322 * 336 *
323 * If the callback returns a [Future], 337 * If the callback returns a [Future],
324 * the future returned by `then` will be completed with 338 * the future returned by `then` will be completed with
325 * the same result of the future returned by the callback. 339 * the same result of the future returned by the callback.
326 * 340 *
327 * If [onError] is not given it forwards the error to `f`. 341 * If [onError] is not given, and this future completes with an error,
342 * the error is forwarded directly to the returned future.
328 * 343 *
329 * In most cases, it is more readable to use [catchError] separately, possibly 344 * In most cases, it is more readable to use [catchError] separately, possibly
330 * with a `test` parameter, instead of handling both value and error in a 345 * with a `test` parameter, instead of handling both value and error in a
331 * single [then] call. 346 * single [then] call.
332 */ 347 */
333 Future then(onValue(T value), { Function onError }); 348 Future then(onValue(T value), { Function onError });
334 349
335 /** 350 /**
336 * Handles errors emitted by this [Future]. 351 * Handles errors emitted by this [Future].
337 * 352 *
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 * theFuture.catchError(thisCompleter.completeError); 607 * theFuture.catchError(thisCompleter.completeError);
593 * 608 *
594 */ 609 */
595 void completeError(Object error, [StackTrace stackTrace]); 610 void completeError(Object error, [StackTrace stackTrace]);
596 611
597 /** 612 /**
598 * Whether the future has been completed. 613 * Whether the future has been completed.
599 */ 614 */
600 bool get isCompleted; 615 bool get isCompleted;
601 } 616 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/convert/json.dart » ('j') | sdk/lib/convert/json.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698