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