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