OLD | NEW |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |