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

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

Issue 11852027: Improve documentation for futures. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Replace [:...:] with backquotes. Created 7 years, 11 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 | no next file » | no next file with comments »
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 * A [Future] is used to obtain a value sometime in the future. Receivers of a 8 * A [Future] represents a delayed computation. It is used to obtain a not-yet
9 * [Future] can obtain the value by passing a callback to [then]. For example: 9 * available value, or error, sometime in the future. Receivers of a
10 * [Future] can register callbacks that handle the value or error once it is
11 * available. For example:
10 * 12 *
11 * Future<int> future = getFutureFromSomewhere(); 13 * Future<int> future = getFuture();
12 * future.then((value) { 14 * future.then((value) => handleValue(value))
13 * print("I received the number $value"); 15 * .catchError((error) => handleError(error));
16 *
17 * A [Future] can be completed in two ways: with a value ("the future succeeds")
18 * or with an error ("the future fails"). Users can install callbacks for each
19 * case. The result of registering a pair of callbacks is a new Future (the
20 * "successor") which in turn is completed with the result of invoking the
21 * corresponding callback. The successor is completed with an error if the
22 * invoked callback throws. For example:
23 *
24 * Future<int> successor = future.then((int value) {
25 * // Invoked when the future is completed with a value.
26 * return 42; // The successor is completed with the value 42.
27 * },
28 * onError: (AsyncError e) {
29 * // Invoked when the future is completed with an error.
30 * if (canHandle(e)) {
31 * return 499; // The successor is completed with the value 499.
32 * } else {
33 * throw e; // The successor is completed with the error e.
34 * }
35 * });
36 *
37 * If a future does not have a successor but is completed with an error, it
38 * forwards the error message to the global error-handler. This special casing
39 * makes sure that no error is silently dropped. However, it also means that
40 * error handlers should be installed early, so that they are present as soon
41 * as a future is completed with an error. The following example demonstrates
42 * this potential bug:
43 *
44 * var future = getFuture();
45 * new Timer(5, (_) {
46 * // The error-handler is only attached 5ms after the future has been
47 * // received. If the future fails in the mean-time it will forward the
48 * // error to the global error-handler, even though there is code (just
49 * // below) to handle the error.
50 * future.then((value) { useValue(value); },
51 * onError: (e) { handleError(e); });
14 * }); 52 * });
15 * 53 *
16 * A future may complete by *succeeding* (producing a value) or *failing* 54 * In general we discourage registering the two callbacks at the same time, but
17 * (producing an error, which may be handled with [catchError]). 55 * prefer to use [then] with one argument (the value handler), and to use
56 * [catchError] for handling errors. The missing callbacks (the error-handler
57 * for [then], and the value-handler for [catchError]), are automatically
58 * configured to "forward" the value/error. Separating value and error-handling
59 * into separate registration calls usually leads to code that is easier to
60 * reason about. In fact it makes asynchronous code very similar to synchronous
61 * code:
18 * 62 *
19 * When a future completes, the following actions happen in order: 63 * // Synchronous code.
64 * try {
65 * int value = foo();
66 * return bar(value);
67 * } catch (e) {
68 * return 499;
69 * }
20 * 70 *
21 * 1. if the future suceeded, handlers registered with [then] are called. 71 * Equivalent asynchronous code, based on futures:
22 * 2. if the future failed, handlers registered with [catchError] are
23 * tested in sequence. Each test returning true is, have its handler
24 * called.
25 * 4. if the future failed, and no handler registered with [catchError] it
26 * is accepting the error, an error is sent to the global error handler.
27 * 72 *
28 * [Future]s are usually not created directly, but with [Completer]s. 73 * Future<int> future = foo(); // foo now returns a future.
74 * future.then((int value) => bar(value))
75 * .catchError((e) => 499);
76 *
77 * Similar to the synchronous code, the error handler (registered with
78 * [catchError]) is handling the errors for exceptions coming from calls to
79 * 'foo', as well as 'bar'. This would not be the case if the error-handler was
80 * registered at the same time as the value-handler.
81 *
82 * Futures can have more than one callback-pairs registered. Each successor is
83 * treated independently and is handled as if it was the only successor.
29 */ 84 */
85 // TODO(floitsch): document chaining.
30 abstract class Future<T> { 86 abstract class Future<T> {
31 /** A future whose value is immediately available. */ 87 /**
88 * A future whose value is available in the next event-loop iteration.
89 *
90 * See [Completer]s, for futures with values that are computed asynchronously.
91 */
32 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value); 92 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
33 93
34 /** A future that completes with an error. */ 94 /**
95 * A future that completes with an error in the next event-loop iteration.
96 *
97 * See [Completer]s, for futures with values that are computed asynchronously.
98 */
35 factory Future.immediateError(var error, [Object stackTrace]) { 99 factory Future.immediateError(var error, [Object stackTrace]) {
36 return new _FutureImpl<T>.immediateError(error, stackTrace); 100 return new _FutureImpl<T>.immediateError(error, stackTrace);
37 } 101 }
38 102
39 /** 103 /**
40 * Creates a future that completes after a delay. 104 * Creates a future that completes after a delay.
41 * 105 *
42 * The future will be completed after [milliseconds] have passed with 106 * The future will be completed after [milliseconds] have passed with
43 * the result of calling [value]. 107 * the result of calling [value]. If [milliseconds] is 0, it completes at the
108 * earliest in the next event-loop iteration.
44 * 109 *
45 * If calling [value] throws, the created future will complete with the 110 * If calling [value] throws, the created future will complete with the
46 * error. 111 * error.
112 *
113 * See [Completer]s, for futures with values that are computed asynchronously.
47 */ 114 */
48 factory Future.delayed(int milliseconds, T value()) { 115 factory Future.delayed(int milliseconds, T value()) {
49 _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value()); 116 _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value());
50 new Timer(milliseconds, (_) => future._sendValue(null)); 117 new Timer(milliseconds, (_) => future._sendValue(null));
51 return future; 118 return future;
52 } 119 }
53 120
54 /** 121 /**
55 * Wait for all the given futures to complete and collect their values. 122 * Wait for all the given futures to complete and collect their values.
56 * 123 *
57 * Returns a future which will complete once all the futures in a list are 124 * Returns a future which will complete once all the futures in a list are
58 * complete. If any of the futures in the list completes with an exception, 125 * complete. If any of the futures in the list completes with an error,
59 * the resulting future also completes with an exception. Otherwise the value 126 * the resulting future also completes with an error. Otherwise the value
60 * of the returned future will be a list of all the values that were produced. 127 * of the returned future will be a list of all the values that were produced.
61 */ 128 */
62 static Future<List> wait(Iterable<Future> futures) { 129 static Future<List> wait(Iterable<Future> futures) {
63 return new _FutureImpl<List>.wait(futures); 130 return new _FutureImpl<List>.wait(futures);
64 } 131 }
65 132
66 /** 133 /**
67 * Perform an async operation for each element of the iterable, in turn. 134 * Perform an async operation for each element of the iterable, in turn.
68 * 135 *
69 * Runs [f] for each element in [input] in order, moving to the next element 136 * Runs [f] for each element in [input] in order, moving to the next element
(...skipping 15 matching lines...) Expand all
85 } 152 }
86 nextElement(null); 153 nextElement(null);
87 return doneSignal; 154 return doneSignal;
88 } 155 }
89 156
90 /** 157 /**
91 * When this future completes with a value, then [onValue] is called with this 158 * When this future completes with a value, then [onValue] is called with this
92 * value. If [this] future is already completed then the invocation of 159 * value. If [this] future is already completed then the invocation of
93 * [onValue] is delayed until the next event-loop iteration. 160 * [onValue] is delayed until the next event-loop iteration.
94 * 161 *
95 * Returns a new [Future] [:f:]. 162 * Returns a new [Future] `f` which is completed with the result of
163 * invoking [onValue] (if [this] completes with a value) or [onError] (if
164 * [this] completes with an error).
96 * 165 *
97 * If [this] is completed with an error then [:f:] is completed with the same 166 * If the invoked callback throws an exception, the returned future `f` is
98 * error. If [this] is completed with a value, then [:f:]'s completion value 167 * completed with the error. If the value thrown is an [AsyncError], it is
99 * depends on the result of invoking [onValue] with [this]' completion value. 168 * used directly, as the error result. Otherwise it is wrapped in an
169 * [AsyncError] first.
100 * 170 *
101 * If [onValue] returns a [Future] [:f2:] then [:f:] and [:f2:] are chained. 171 * If the invoked callback returns a [Future] `f2` then `f` and `f2` are
102 * That is, [:f:] is completed with the completion value of [:f2:]. 172 * chained. That is, `f` is completed with the completion value of `f2`.
103 * 173 *
104 * Otherwise [:f:] is completed with the return value of [onValue]. 174 * If [onError] is not given, it is equivalent to `(e) { throw e; }`. That
105 * 175 * is, it forwards the error to `f`.
106 * If [onValue] throws an exception, the returned future will receive the
107 * exception. If the value thrown is an [AsyncError], it is used directly,
108 * as the error result, otherwise it is wrapped in an [AsyncError] first.
109 *
110 * If [onError] is provided, it is called if this future completes with an
111 * error, and its return value/throw behavior is handled the same way as
112 * for [catchError] without a [:test:] argument.
113 * 176 *
114 * In most cases, it is more readable to use [catchError] separately, possibly 177 * In most cases, it is more readable to use [catchError] separately, possibly
115 * with a [:test:] parameter, instead of handling both value and error in a 178 * with a `test` parameter, instead of handling both value and error in a
116 * single [then] call. 179 * single [then] call.
117 */ 180 */
118 Future then(onValue(T value), { onError(AsyncError asyncError) }); 181 Future then(onValue(T value), { onError(AsyncError asyncError) });
119 182
120 /** 183 /**
121 * Handles errors emitted by this [Future]. 184 * Handles errors emitted by this [Future].
122 * 185 *
123 * When this future completes with an error, first [test] is called with the 186 * Returns a new [Future] `f`.
124 * error's value.
125 * 187 *
126 * If [test] returns [true], [onError] is called with the error 188 * When [this] completes with a value, the value is forwarded to `f`
127 * wrapped in an [AsyncError]. The result of [onError] is handled exactly as 189 * unmodified. That is, `f` completes with the same value.
128 * [then]'s [onValue]. 190 *
191 * When [this] completes with an error, [test] is called with the
192 * error's value. If the invocation returns [true], [onError] is called with
193 * the error wrapped in an [AsyncError]. The result of [onError] is handled
194 * exactly the same as for [then]'s [onError].
129 * 195 *
130 * If [test] returns false, the exception is not handled by [onError], but is 196 * If [test] returns false, the exception is not handled by [onError], but is
131 * emitted by the returned Future unmodified. 197 * thrown unmodified, thus forwarding it to `f`.
132 * 198 *
133 * If [test] is omitted, it defaults to a function that always returns true. 199 * If [test] is omitted, it defaults to a function that always returns true.
134 * 200 *
135 * Example: 201 * Example:
136 * foo 202 *
137 * .catchError(..., test: (e) => e is ArgumentError) 203 * foo
138 * .catchError(..., test: (e) => e is NoSuchMethodError) 204 * .catchError(..., test: (e) => e is ArgumentError)
139 * .then((v) { ... }); 205 * .catchError(..., test: (e) => e is NoSuchMethodError)
206 * .then((v) { ... });
207 *
208 * This method is equivalent to:
209 *
210 * Future catchError(onError(AsyncError asyncError),
211 * {bool test(Object error)}) {
212 * this.then((v) => v, // Forward the value.
213 * // But handle errors, if the [test] succeeds.
214 * onError: (AsyncError e) {
215 * if (test == null || test(e.error)) {
216 * return onError(e);
217 * }
218 * throw e;
219 * });
220 * }
221 *
140 */ 222 */
141 Future catchError(onError(AsyncError asyncError), 223 Future catchError(onError(AsyncError asyncError),
142 {bool test(Object error)}); 224 {bool test(Object error)});
143 225
144 /** 226 /**
145 * Register a function to be called when this future completes. 227 * Register a function to be called when this future completes.
146 * 228 *
147 * The [action] function is called when this future completes, whether it 229 * The [action] function is called when this future completes, whether it
148 * does so with a value or with an error. 230 * does so with a value or with an error.
149 * 231 *
150 * This is the asynchronous equivalent of a "finally" block. 232 * This is the asynchronous equivalent of a "finally" block.
151 * 233 *
152 * The future returned by this call, [:f:], will complete the same way 234 * The future returned by this call, `f`, will complete the same way
153 * as this future unless an error occurs in the [action] call, or in 235 * as this future unless an error occurs in the [action] call, or in
154 * a [Future] returned by the [action] call. If the call to [action] 236 * a [Future] returned by the [action] call. If the call to [action]
155 * does not return a future, its return value is ignored. 237 * does not return a future, its return value is ignored.
156 * 238 *
157 * If the call to [action] throws, then [:f:] is completed with the 239 * If the call to [action] throws, then `f` is completed with the
158 * thrown error. 240 * thrown error.
159 * 241 *
160 * If the call to [action] returns a [Future], [:f2:], then completion of 242 * If the call to [action] returns a [Future], `f2`, then completion of
161 * [:f:] is delayed until [:f2:] completes. If [:f2:] completes with 243 * `f` is delayed until `f2` completes. If `f2` completes with
162 * an error, that will be the result of [:f:] too. 244 * an error, that will be the result of `f` too.
245 *
246 * This method is equivalent to:
247 *
248 * Future<T> whenComplete(action()) {
249 * this.then((v) {
250 * action();
251 * return v
252 * },
253 * onError: (AsyncError e) {
254 * action();
255 * throw e;
256 * });
257 * }
163 */ 258 */
164 Future<T> whenComplete(action()); 259 Future<T> whenComplete(action());
165 260
166 /** 261 /**
167 * Creates a [Stream] that sends [this]' completion value, data or error, to 262 * Creates a [Stream] that sends [this]' completion value, data or error, to
168 * its subscribers. The stream closes after the completion value. 263 * its subscribers. The stream closes after the completion value.
169 */ 264 */
170 Stream<T> asStream(); 265 Stream<T> asStream();
171 } 266 }
172 267
(...skipping 30 matching lines...) Expand all
203 * All listeners on the future will be immediately informed about the value. 298 * All listeners on the future will be immediately informed about the value.
204 */ 299 */
205 void complete([T value]); 300 void complete([T value]);
206 301
207 /** 302 /**
208 * Complete [future] with an error. 303 * Complete [future] with an error.
209 * 304 *
210 * Completing a future with an error indicates that an exception was thrown 305 * Completing a future with an error indicates that an exception was thrown
211 * while trying to produce a value. 306 * while trying to produce a value.
212 * 307 *
213 * The argument [exception] should not be [:null:]. 308 * The argument [exception] should not be `null`.
214 * 309 *
215 * If [exception] is an [AsyncError], it is used directly as the error 310 * If [exception] is an [AsyncError], it is used directly as the error
216 * message sent to the future's listeners, and [stackTrace] is ignored. 311 * message sent to the future's listeners, and [stackTrace] is ignored.
217 * 312 *
218 * Otherwise the [exception] and an optional [stackTrace] is combined into an 313 * Otherwise the [exception] and an optional [stackTrace] is combined into an
219 * [AsyncError] and sent to this future's listeners. 314 * [AsyncError] and sent to this future's listeners.
220 */ 315 */
221 void completeError(Object exception, [Object stackTrace]); 316 void completeError(Object exception, [Object stackTrace]);
222 } 317 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698