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

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: Add fix for 17424 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 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.
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 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.
49 * // received. If the future fails in the mean-time it will forward the 53 * // received. If the future fails before that, the error is forwarded
50 * // error to the global error-handler, even though there is code (just 54 * // to the global error-handler, even though there is code (just
51 * // below) to handle the error. 55 * // 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 * 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.
57 * prefer to use [then] with one argument (the value handler), and to use 61 * by using [then] with one argument (the value handler) and
58 * [catchError] for handling errors. The missing callbacks (the error-handler 62 * using [catchError] for handling errors.
59 * for [then], and the value-handler for [catchError]), are automatically 63 * The omitted callbacks (the error-handler for [then],
60 * configured to "forward" the value/error. Separating value and error-handling 64 * 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
61 * into separate registration calls usually leads to code that is easier to 65 * configured to forward the value/error directly to the successor.
62 * reason about. In fact it makes asynchronous code very similar to synchronous 66 * Separating value and error-handling into separate registration calls
63 * code: 67 * usually leads to code that is easier to reason about.
68 * It also makes asynchronous code very similar to synchronous code:
64 * 69 *
65 * // Synchronous code. 70 * // Synchronous code.
66 * try { 71 * try {
67 * int value = foo(); 72 * int value = foo();
68 * return bar(value); 73 * return bar(value);
69 * } catch (e) { 74 * } catch (e) {
70 * return 499; 75 * return 499;
71 * } 76 * }
72 * 77 *
73 * Equivalent asynchronous code, based on futures: 78 * Equivalent asynchronous code, based on futures:
74 * 79 *
75 * Future<int> future = foo(); // foo now returns a future. 80 * Future<int> future = new Future(foo); // Result of foo() as a future.
76 * future.then((int value) => bar(value)) 81 * future.then((int value) => bar(value))
77 * .catchError((e) => 499); 82 * .catchError((e) => 499);
78 * 83 *
79 * Similar to the synchronous code, the error handler (registered with 84 * Similar to the synchronous code, the error handler (registered with
80 * [catchError]) is handling the errors for exceptions coming from calls to 85 * [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 86 * If the error-handler had been registered as the `onError` parameter of
82 * registered at the same time as the value-handler. 87 * the `then` call, it would not catch errors from the `bar` call.
83 * 88 *
84 * Futures can have more than one callback-pairs registered. Each successor is 89 * 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. 90 * treated independently and is handled as if it was the only successor.
91 *
92 * A future may also fail to ever complete. In that case, no callbacks are
93 * called.
86 */ 94 */
87 // TODO(floitsch): document chaining.
88 abstract class Future<T> { 95 abstract class Future<T> {
89 // The `_nullFuture` is a completed Future with the value `null`. 96 // The `_nullFuture` is a completed Future with the value `null`.
90 static final _Future _nullFuture = new Future.value(null); 97 static final _Future _nullFuture = new Future.value(null);
91 98
92 /** 99 /**
93 * Creates a future containing the result of calling [computation] 100 * Creates a future containing the result of calling [computation]
94 * asynchronously with [Timer.run]. 101 * asynchronously with [Timer.run].
95 * 102 *
96 * If the result of executing [computation] throws, the returned future is 103 * If the result of executing [computation] throws, the returned future is
97 * completed with the error. 104 * completed with the error.
98 * 105 *
99 * If the returned value is itself a [Future], completion of 106 * If the returned value is itself a [Future], completion of
100 * the created future will wait until the returned future completes, 107 * the created future will wait until the returned future completes,
101 * and will then complete with the same result. 108 * and will then complete with the same result.
102 * 109 *
103 * If a value is returned, it becomes the result of the created future. 110 * If a non-future value is returned, the returned future is completed
111 * with that value.
104 */ 112 */
105 factory Future(computation()) { 113 factory Future(computation()) {
106 _Future result = new _Future<T>(); 114 _Future result = new _Future<T>();
107 Timer.run(() { 115 Timer.run(() {
108 try { 116 try {
109 result._complete(computation()); 117 result._complete(computation());
110 } catch (e, s) { 118 } catch (e, s) {
111 result._completeError(e, s); 119 result._completeError(e, s);
112 } 120 }
113 }); 121 });
114 return result; 122 return result;
115 } 123 }
116 124
117 /** 125 /**
118 * Creates a future containing the result of calling [computation] 126 * Creates a future containing the result of calling [computation]
119 * asynchronously with [scheduleMicrotask]. 127 * asynchronously with [scheduleMicrotask].
120 * 128 *
121 * If the result of executing [computation] throws, the returned future is 129 * If executing [computation] throws,
122 * completed with the error. 130 * the returned future is completed with the thrown error.
123 * 131 *
124 * If the returned value is itself a [Future], completion of 132 * If calling [computation] returns a [Future], completion of
125 * the created future will wait until the returned future completes, 133 * the created future will wait until the returned future completes,
126 * and will then complete with the same result. 134 * and will then complete with the same result.
127 * 135 *
128 * If a value is returned, it becomes the result of the created future. 136 * If calling [computation] returns a non-future value,
137 * the returned future is completed with that value.
129 */ 138 */
130 factory Future.microtask(computation()) { 139 factory Future.microtask(computation()) {
131 _Future result = new _Future<T>(); 140 _Future result = new _Future<T>();
132 scheduleMicrotask(() { 141 scheduleMicrotask(() {
133 try { 142 try {
134 result._complete(computation()); 143 result._complete(computation());
135 } catch (e, s) { 144 } catch (e, s) {
136 result._completeError(e, s); 145 result._completeError(e, s);
137 } 146 }
138 }); 147 });
139 return result; 148 return result;
140 } 149 }
141 150
142 /** 151 /**
143 * Creates a future containing the result of immediately calling 152 * Creates a future containing the result of immediately calling
144 * [computation]. 153 * [computation].
145 * 154 *
146 * If calling [computation] throws, the returned future is completed with the 155 * If calling [computation] throws, the returned future is completed with the
147 * error. 156 * error.
148 * 157 *
149 * If the returned value is itself a [Future], completion of 158 * If calling [computation] returns a [Future], completion of
150 * the created future will wait until the returned future completes, 159 * the created future will wait until the returned future completes,
151 * and will then complete with the same result. 160 * and will then complete with the same result.
161 *
162 * If calling [computation] returns a non-future value,
163 * the returned future is completed with that value.
152 */ 164 */
153 factory Future.sync(computation()) { 165 factory Future.sync(computation()) {
154 try { 166 try {
155 var result = computation(); 167 var result = computation();
156 return new Future<T>.value(result); 168 return new Future<T>.value(result);
157 } catch (error, stackTrace) { 169 } catch (error, stackTrace) {
158 return new Future<T>.error(error, stackTrace); 170 return new Future<T>.error(error, stackTrace);
159 } 171 }
160 } 172 }
161 173
162 /** 174 /**
163 * A future whose value is available in the next event-loop iteration. 175 * A future whose value is available in the next event-loop iteration.
164 * 176 *
165 * If [value] is not a [Future], using this constructor is equivalent 177 * If [value] is not a [Future], using this constructor is equivalent
166 * to [:new Future<T>.sync(() => value):]. 178 * to [:new Future<T>.sync(() => value):].
167 * 179 *
168 * See [Completer] to create a Future and complete it later. 180 * Use [Completer] to create a Future and complete it later.
169 */ 181 */
170 factory Future.value([value]) { 182 factory Future.value([value]) {
171 return new _Future<T>.immediate(value); 183 return new _Future<T>.immediate(value);
172 } 184 }
173 185
174 /** 186 /**
175 * A future that completes with an error in the next event-loop iteration. 187 * A future that completes with an error in the next event-loop iteration.
176 * 188 *
177 * See [Completer] to create a Future and complete it later. 189 * Use [Completer] to create a Future and complete it later.
178 */ 190 */
179 factory Future.error(Object error, [StackTrace stackTrace]) { 191 factory Future.error(Object error, [StackTrace stackTrace]) {
180 return new _Future<T>.immediateError(error, stackTrace); 192 return new _Future<T>.immediateError(error, stackTrace);
181 } 193 }
182 194
183 /** 195 /**
184 * Creates a future that completes after a delay. 196 * Creates a future that completes after a delay.
185 * 197 *
186 * The future will be completed after the given [duration] has passed with 198 * 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 199 * the result of calling [computation]. If the duration is 0 or less, it
188 * completes no sooner than in the next event-loop iteration. 200 * completes no sooner than in the next event-loop iteration.
189 * 201 *
190 * If [computation] is not given or [:null:] then it will behave as if 202 * If [computation] is omitted,
191 * [computation] was set to [:() => null:]. That is, it will complete with 203 * it will be treated as if [computation] was set to `() => null`,
192 * [:null:]. 204 * and the future will eventually complete with the `null` value.
193 * 205 *
194 * If calling [computation] throws, the created future will complete with the 206 * If calling [computation] throws, the created future will complete with the
195 * error. 207 * error.
196 * 208 *
197 * See [Completer]s, for futures with values that are computed asynchronously. 209 * See also [Completer] for a way to complete a future at a later
210 * time that isn't a known fixed duration.
198 */ 211 */
199 factory Future.delayed(Duration duration, [T computation()]) { 212 factory Future.delayed(Duration duration, [T computation()]) {
200 Completer completer = new Completer.sync(); 213 Completer completer = new Completer.sync();
201 Future result = completer.future; 214 Future result = completer.future;
202 if (computation != null) { 215 if (computation != null) {
203 result = result.then((ignored) => computation()); 216 result = result.then((ignored) => computation());
204 } 217 }
205 new Timer(duration, () { completer.complete(null); }); 218 new Timer(duration, () { completer.complete(null); });
206 return result; 219 return result;
207 } 220 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 * 322 *
310 * Returns a new [Future] 323 * Returns a new [Future]
311 * which is completed with the result of the call to `onValue` 324 * which is completed with the result of the call to `onValue`
312 * (if this future completes with a value) 325 * (if this future completes with a value)
313 * or to `onError` (if this future completes with an error). 326 * or to `onError` (if this future completes with an error).
314 * 327 *
315 * If the invoked callback throws, 328 * If the invoked callback throws,
316 * the returned future is completed with the thrown error 329 * the returned future is completed with the thrown error
317 * and a stack trace for the error. 330 * and a stack trace for the error.
318 * In the case of `onError`, 331 * In the case of `onError`,
319 * if the exception thrown is the same as the argument to `onError`, 332 * if the exception thrown is `identical` to the error argument to `onError`,
320 * the throw is considered a rethrow, 333 * the throw is considered a rethrow,
321 * and the original stack trace is used instead. 334 * and the original stack trace is used instead.
322 * 335 *
323 * If the callback returns a [Future], 336 * If the callback returns a [Future],
324 * the future returned by `then` will be completed with 337 * the future returned by `then` will be completed with
325 * the same result of the future returned by the callback. 338 * the same result of the future returned by the callback.
326 * 339 *
327 * If [onError] is not given it forwards the error to `f`. 340 * If [onError] is not given, and this future completes with an error,
341 * the error is forwarded directly to the returned future.
328 * 342 *
329 * In most cases, it is more readable to use [catchError] separately, possibly 343 * 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 344 * with a `test` parameter, instead of handling both value and error in a
331 * single [then] call. 345 * single [then] call.
332 */ 346 */
333 Future then(onValue(T value), { Function onError }); 347 Future then(onValue(T value), { Function onError });
334 348
335 /** 349 /**
336 * Handles errors emitted by this [Future]. 350 * Handles errors emitted by this [Future].
337 * 351 *
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
592 * theFuture.catchError(thisCompleter.completeError); 606 * theFuture.catchError(thisCompleter.completeError);
593 * 607 *
594 */ 608 */
595 void completeError(Object error, [StackTrace stackTrace]); 609 void completeError(Object error, [StackTrace stackTrace]);
596 610
597 /** 611 /**
598 * Whether the future has been completed. 612 * Whether the future has been completed.
599 */ 613 */
600 bool get isCompleted; 614 bool get isCompleted;
601 } 615 }
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