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 /// A type representing values that are either `Future<T>` or `T`. | 7 /// A type representing values that are either `Future<T>` or `T`. |
| 8 /// | 8 /// |
| 9 /// This class declaration is a public stand-in for an internal | 9 /// This class declaration is a public stand-in for an internal |
| 10 /// future-or-value generic type. References to this class are resolved to the | 10 /// future-or-value generic type. References to this class are resolved to the |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 50 * A [Future] is used to represent a potential value, or error, | 50 * A [Future] is used to represent a potential value, or error, |
| 51 * that will be available at some time in the future. | 51 * that will be available at some time in the future. |
| 52 * Receivers of a [Future] can register callbacks | 52 * Receivers of a [Future] can register callbacks |
| 53 * that handle the value or error once it is available. | 53 * that handle the value or error once it is available. |
| 54 * For example: | 54 * For example: |
| 55 * | 55 * |
| 56 * Future<int> future = getFuture(); | 56 * Future<int> future = getFuture(); |
| 57 * future.then((value) => handleValue(value)) | 57 * future.then((value) => handleValue(value)) |
| 58 * .catchError((error) => handleError(error)); | 58 * .catchError((error) => handleError(error)); |
| 59 * | 59 * |
| 60 * A [Future] can complete in two ways: | 60 * A [Future] can be completed in two ways: |
| 61 * with a value ("the future succeeds") | 61 * with a value ("the future succeeds") |
| 62 * or with an error ("the future fails"). | 62 * or with an error ("the future fails"). |
| 63 * Users can install callbacks for each case. | 63 * Users can install callbacks for each case. |
| 64 * In some cases we say that a future is completed with another future. | |
|
floitsch
2017/05/31 15:28:27
Put a line before here. (I think this should be a
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Done.
| |
| 65 * In that case, the other future is waited for, and when it completes, | |
|
floitsch
2017/05/31 15:28:27
... with another future. This is a short way of st
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Used with slight rewording.
| |
| 66 * the first future is completed in the same way, with the same value or error. | |
| 67 * | |
| 64 * The result of registering a pair of callbacks is a new Future (the | 68 * The result of registering a pair of callbacks is a new Future (the |
| 65 * "successor") which in turn is completed with the result of invoking the | 69 * "successor") which in turn is completed with the result of invoking the |
| 66 * corresponding callback. | 70 * corresponding callback. |
| 67 * The successor is completed with an error if the invoked callback throws. | 71 * The successor is completed with an error if the invoked callback throws. |
| 68 * For example: | 72 * For example: |
| 69 * | 73 * ``` |
| 70 * Future<int> successor = future.then((int value) { | 74 * Future<int> successor = future.then((int value) { |
| 71 * // Invoked when the future is completed with a value. | 75 * // Invoked when the future is completed with a value. |
| 72 * return 42; // The successor is completed with the value 42. | 76 * return 42; // The successor is completed with the value 42. |
| 73 * }, | 77 * }, |
| 74 * onError: (e) { | 78 * onError: (e) { |
| 75 * // Invoked when the future is completed with an error. | 79 * // Invoked when the future is completed with an error. |
| 76 * if (canHandle(e)) { | 80 * if (canHandle(e)) { |
| 77 * return 499; // The successor is completed with the value 499. | 81 * return 499; // The successor is completed with the value 499. |
| 78 * } else { | 82 * } else { |
| 79 * throw e; // The successor is completed with the error e. | 83 * throw e; // The successor is completed with the error e. |
| 80 * } | 84 * } |
| 81 * }); | 85 * }); |
| 86 * ``` | |
| 82 * | 87 * |
| 83 * If a future does not have a successor when it completes with an error, | 88 * If a future does not have a successor when it completes with an error, |
| 84 * it forwards the error message to the global error-handler. | 89 * it forwards the error message to the global error-handler. |
| 85 * This behavior makes sure that no error is silently dropped. | 90 * This behavior makes sure that no error is silently dropped. |
| 86 * However, it also means that error handlers should be installed early, | 91 * However, it also means that error handlers should be installed early, |
| 87 * so that they are present as soon as a future is completed with an error. | 92 * so that they are present as soon as a future is completed with an error. |
| 88 * The following example demonstrates this potential bug: | 93 * The following example demonstrates this potential bug: |
| 89 * | 94 * ``` |
| 90 * var future = getFuture(); | 95 * var future = getFuture(); |
| 91 * new Timer(new Duration(milliseconds: 5), () { | 96 * new Timer(new Duration(milliseconds: 5), () { |
| 92 * // The error-handler is not attached until 5 ms after the future has | 97 * // The error-handler is not attached until 5 ms after the future has |
| 93 * // been received. If the future fails before that, the error is | 98 * // been received. If the future fails before that, the error is |
| 94 * // forwarded to the global error-handler, even though there is code | 99 * // forwarded to the global error-handler, even though there is code |
| 95 * // (just below) to eventually handle the error. | 100 * // (just below) to eventually handle the error. |
| 96 * future.then((value) { useValue(value); }, | 101 * future.then((value) { useValue(value); }, |
| 97 * onError: (e) { handleError(e); }); | 102 * onError: (e) { handleError(e); }); |
| 98 * }); | 103 * }); |
| 104 * ``` | |
| 99 * | 105 * |
| 100 * When registering callbacks, it's often more readable to register the two | 106 * When registering callbacks, it's often more readable to register the two |
| 101 * callbacks separately, by first using [then] with one argument | 107 * callbacks separately, by first using [then] with one argument |
| 102 * (the value handler) and using a second [catchError] for handling errors. | 108 * (the value handler) and using a second [catchError] for handling errors. |
| 103 * Each of these will forward the result that they don't handle | 109 * Each of these will forward the result that they don't handle |
| 104 * to their successors, and together they handle both value and error result. | 110 * to their successors, and together they handle both value and error result. |
| 105 * It also has the additional benefit of the [catchError] handling errors in the | 111 * It also has the additional benefit of the [catchError] handling errors in the |
| 106 * [then] value callback too. | 112 * [then] value callback too. |
| 107 * Using sequential handlers instead of parallel ones often leads to code that | 113 * Using sequential handlers instead of parallel ones often leads to code that |
| 108 * is easier to reason about. | 114 * is easier to reason about. |
| 109 * It also makes asynchronous code very similar to synchronous code: | 115 * It also makes asynchronous code very similar to synchronous code: |
| 110 * | 116 * ``` |
| 111 * // Synchronous code. | 117 * // Synchronous code. |
| 112 * try { | 118 * try { |
| 113 * int value = foo(); | 119 * int value = foo(); |
| 114 * return bar(value); | 120 * return bar(value); |
| 115 * } catch (e) { | 121 * } catch (e) { |
| 116 * return 499; | 122 * return 499; |
| 117 * } | 123 * } |
| 124 * ``` | |
| 118 * | 125 * |
| 119 * Equivalent asynchronous code, based on futures: | 126 * Equivalent asynchronous code, based on futures: |
| 120 * | 127 * ``` |
| 121 * Future<int> future = new Future(foo); // Result of foo() as a future. | 128 * Future<int> future = new Future(foo); // Result of foo() as a future. |
| 122 * future.then((int value) => bar(value)) | 129 * future.then((int value) => bar(value)) |
| 123 * .catchError((e) => 499); | 130 * .catchError((e) => 499); |
| 131 * ``` | |
| 124 * | 132 * |
| 125 * Similar to the synchronous code, the error handler (registered with | 133 * Similar to the synchronous code, the error handler (registered with |
| 126 * [catchError]) is handling any errors thrown by either `foo` or `bar`. | 134 * [catchError]) is handling any errors thrown by either `foo` or `bar`. |
| 127 * If the error-handler had been registered as the `onError` parameter of | 135 * If the error-handler had been registered as the `onError` parameter of |
| 128 * the `then` call, it would not catch errors from the `bar` call. | 136 * the `then` call, it would not catch errors from the `bar` call. |
| 129 * | 137 * |
| 130 * Futures can have more than one callback-pair registered. Each successor is | 138 * Futures can have more than one callback-pair registered. Each successor is |
| 131 * treated independently and is handled as if it was the only successor. | 139 * treated independently and is handled as if it was the only successor. |
| 132 * | 140 * |
| 133 * A future may also fail to ever complete. In that case, no callbacks are | 141 * A future may also fail to ever complete. In that case, no callbacks are |
| 134 * called. | 142 * called. |
| 135 */ | 143 */ |
| 136 abstract class Future<T> { | 144 abstract class Future<T> { |
| 137 // The `_nullFuture` is a completed Future with the value `null`. | 145 /// A `Future<Null>` completed with `null`. |
|
floitsch
2017/05/31 15:28:27
Should we make this one public? It's quite common.
Lasse Reichstein Nielsen
2017/06/02 05:53:39
I'd want to iterate a little on the name if we mak
| |
| 138 static final _Future<Null> _nullFuture = new _Future<Null>.value(null); | 146 static final _Future<Null> _nullFuture = new _Future<Null>.value(null); |
| 139 | 147 |
| 148 /// A `Future<bool>` completed with `false`. | |
| 149 static final _Future<bool> _falseFuture = new _Future<bool>.value(false); | |
| 150 | |
| 140 /** | 151 /** |
| 141 * Creates a future containing the result of calling [computation] | 152 * Creates a future containing the result of calling [computation] |
| 142 * asynchronously with [Timer.run]. | 153 * asynchronously with [Timer.run]. |
| 143 * | 154 * |
| 144 * If the result of executing [computation] throws, the returned future is | 155 * If the result of executing [computation] throws, the returned future is |
| 145 * completed with the error. | 156 * completed with the error. |
| 146 * | 157 * |
| 147 * If the returned value is itself a [Future], completion of | 158 * If the returned value is itself a [Future], completion of |
| 148 * the created future will wait until the returned future completes, | 159 * the created future will wait until the returned future completes, |
| 149 * and will then complete with the same result. | 160 * and will then complete with the same result. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 future._asyncCompleteError( | 230 future._asyncCompleteError( |
| 220 _nonNullError(replacement.error), replacement.stackTrace); | 231 _nonNullError(replacement.error), replacement.stackTrace); |
| 221 } else { | 232 } else { |
| 222 future._asyncCompleteError(error, stackTrace); | 233 future._asyncCompleteError(error, stackTrace); |
| 223 } | 234 } |
| 224 return future; | 235 return future; |
| 225 } | 236 } |
| 226 } | 237 } |
| 227 | 238 |
| 228 /** | 239 /** |
| 229 * A future whose value is available in the next event-loop iteration. | 240 * Creates a future completed with [result]. |
|
floitsch
2017/05/31 15:28:27
a future, completed with...
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Don't think that would work, there'd be no subject
| |
| 230 * | 241 * |
| 231 * If [result] is not a [Future], using this constructor is equivalent | 242 * If [result] is a future, this creates a new future that waits for the |
|
floitsch
2017/05/31 15:28:28
"this creates" sounds bad.
The created future wai
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Done.
| |
| 232 * to `new Future<T>.sync(() => result)`. | 243 * [result] future to complete, and then completes with the same result. |
|
floitsch
2017/05/31 15:28:27
Maybe mention that this means that a Future.value
| |
| 244 * | |
| 245 * If [result] is not a [Future], this creates a future that is already | |
|
floitsch
2017/05/31 15:28:27
not a [Future], the returned future
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Done + reworded.
| |
| 246 * completed with th [result] value | |
|
floitsch
2017/05/31 15:28:28
the
Lasse Reichstein Nielsen
2017/06/02 05:53:38
Done.
| |
| 247 * equivalent to `new Future<T>.sync(() => result)`. | |
| 233 * | 248 * |
| 234 * Use [Completer] to create a future and complete it later. | 249 * Use [Completer] to create a future and complete it later. |
| 235 */ | 250 */ |
| 236 factory Future.value([FutureOr<T> result]) { | 251 factory Future.value([FutureOr<T> result]) { |
|
floitsch
2017/05/31 15:28:27
"result" sounds weird.
Probably just "value"?
Lasse Reichstein Nielsen
2017/06/02 05:53:38
Done.
| |
| 237 return new _Future<T>.immediate(result); | 252 return new _Future<T>.immediate(result); |
| 238 } | 253 } |
| 239 | 254 |
| 240 /** | 255 /** |
| 241 * A future that completes with an error in the next event-loop iteration. | 256 * Creates a future that completes with an error. |
| 257 * | |
| 258 * The created future will be completed with an error in a future microtask. | |
| 259 * This allows enough time for someone to add an error handler on the future. | |
| 260 * If an error handler isn't added before the future completes, the error | |
| 261 * will be considered unhandled. | |
| 242 * | 262 * |
| 243 * If [error] is `null`, it is replaced by a [NullThrownError]. | 263 * If [error] is `null`, it is replaced by a [NullThrownError]. |
| 244 * | 264 * |
| 245 * Use [Completer] to create a future and complete it later. | 265 * Use [Completer] to create a future and complete it later. |
| 246 */ | 266 */ |
| 247 factory Future.error(Object error, [StackTrace stackTrace]) { | 267 factory Future.error(Object error, [StackTrace stackTrace]) { |
| 248 error = _nonNullError(error); | 268 error = _nonNullError(error); |
| 249 if (!identical(Zone.current, _ROOT_ZONE)) { | 269 if (!identical(Zone.current, _ROOT_ZONE)) { |
| 250 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); | 270 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); |
| 251 if (replacement != null) { | 271 if (replacement != null) { |
| 252 error = _nonNullError(replacement.error); | 272 error = _nonNullError(replacement.error); |
| 253 stackTrace = replacement.stackTrace; | 273 stackTrace = replacement.stackTrace; |
| 254 } | 274 } |
| 255 } | 275 } |
| 256 return new _Future<T>.immediateError(error, stackTrace); | 276 return new _Future<T>.immediateError(error, stackTrace); |
| 257 } | 277 } |
| 258 | 278 |
| 259 /** | 279 /** |
| 260 * Creates a future that runs its computation after a delay. | 280 * Creates a future that runs its computation after a delay. |
| 261 * | 281 * |
| 262 * The [computation] will be executed after the given [duration] has passed, | 282 * The [computation] will be executed after the given [duration] has passed, |
| 263 * and the future is completed with the result. | 283 * and the future is completed with the result of the computation, |
| 284 * | |
| 264 * If the duration is 0 or less, | 285 * If the duration is 0 or less, |
| 265 * it completes no sooner than in the next event-loop iteration. | 286 * it completes no sooner than in the next event-loop iteration, |
| 287 * after microtasks have run. | |
|
floitsch
2017/05/31 15:28:27
after all microtasks
Lasse Reichstein Nielsen
2017/06/02 05:53:39
OK, but technically not correct - there might be m
| |
| 266 * | 288 * |
| 267 * If [computation] is omitted, | 289 * If [computation] is omitted, |
| 268 * it will be treated as if [computation] was set to `() => null`, | 290 * it will be treated as if [computation] was `() => null`, |
| 269 * and the future will eventually complete with the `null` value. | 291 * and the future will eventually complete with the `null` value. |
| 270 * | 292 * |
| 271 * If calling [computation] throws, the created future will complete with the | 293 * If calling [computation] throws, the created future will complete with the |
| 272 * error. | 294 * error. |
| 273 * | 295 * |
| 274 * See also [Completer] for a way to create and complete a future at a | 296 * See also [Completer] for a way to create and complete a future at a |
| 275 * later time that isn't necessarily after a known fixed duration. | 297 * later time that isn't necessarily after a known fixed duration. |
| 276 */ | 298 */ |
| 277 factory Future.delayed(Duration duration, [FutureOr<T> computation()]) { | 299 factory Future.delayed(Duration duration, [FutureOr<T> computation()]) { |
| 278 _Future<T> result = new _Future<T>(); | 300 _Future<T> result = new _Future<T>(); |
| 279 new Timer(duration, () { | 301 new Timer(duration, () { |
| 280 try { | 302 try { |
| 281 result._complete(computation?.call()); | 303 result._complete(computation?.call()); |
| 282 } catch (e, s) { | 304 } catch (e, s) { |
| 283 _completeWithErrorCallback(result, e, s); | 305 _completeWithErrorCallback(result, e, s); |
| 284 } | 306 } |
| 285 }); | 307 }); |
| 286 return result; | 308 return result; |
| 287 } | 309 } |
| 288 | 310 |
| 289 /** | 311 /** |
| 290 * Wait for all the given futures to complete and collect their values. | 312 * Waits for multiple futures to complete and collects their results. |
| 291 * | 313 * |
| 292 * Returns a future which will complete once all the futures in a list | 314 * Returns a future which will complete once all the provided futures |
| 293 * have completed. | 315 * have completed, either with their results, or with an error if either |
| 316 * of the provided futures fail. | |
| 294 * | 317 * |
| 295 * The value of the returned future will be a list of all the values that | 318 * The value of the returned future will be a list of all the values that |
| 296 * were produced. | 319 * were produced. |
| 297 * | 320 * |
| 298 * If any of the given futures completes with an error, then the returned | 321 * If any future completes with an error, |
| 299 * future completes with that error. If other futures complete with errors, | 322 * then the returned future completes with that error. |
| 300 * those errors are discarded. | 323 * If further futures also complete with errors, those errors are discarded. |
| 301 * | 324 * |
| 302 * If `eagerError` is true, the returned future completes with an error | 325 * If `eagerError` is true, the returned future completes with an error |
| 303 * immediately on the first error from one of the futures. Otherwise all | 326 * immediately on the first error from one of the futures. Otherwise all |
| 304 * futures must complete before the returned future is completed (still with | 327 * futures must complete before the returned future is completed (still with |
| 305 * the first error; the remaining errors are silently dropped). | 328 * the first error; the remaining errors are silently dropped). |
| 306 * | 329 * |
| 307 * In the case of an error, [cleanUp] (if provided), is invoked on any | 330 * In the case of an error, [cleanUp] (if provided), is invoked on any |
| 308 * non-null result of successful futures. | 331 * non-null result of successful futures. |
| 309 * This makes it posible to `cleanUp` resources that would otherwise be | 332 * This makes it posible to "clean up" resources that would otherwise be |
| 310 * lost (since the returned future does not provide access to these values). | 333 * lost since the returned future does not provide access to these values. |
| 311 * The [cleanup] function is unused if there is no error. | 334 * The [cleanUp] function is unused if there is no error. |
| 312 * | 335 * |
| 313 * The call to `cleanUp` should not throw. If it does, the error will be an | 336 * The call to [cleanUp] should not throw. If it does, the error will be an |
| 314 * uncaught asynchronous error. | 337 * uncaught asynchronous error. |
| 315 */ | 338 */ |
| 316 static Future<List<T>> wait<T>(Iterable<Future<T>> futures, | 339 static Future<List<T>> wait<T>(Iterable<Future<T>> futures, |
| 317 {bool eagerError: false, void cleanUp(T successValue)}) { | 340 {bool eagerError: false, void cleanUp(T successValue)}) { |
| 318 final _Future<List<T>> result = new _Future<List<T>>(); | 341 final _Future<List<T>> result = new _Future<List<T>>(); |
| 319 List<T> values; // Collects the values. Set to null on error. | 342 List<T> values; // Collects the values. Set to null on error. |
| 320 int remaining = 0; // How many futures are we waiting for. | 343 int remaining = 0; // How many futures are we waiting for. |
| 321 var error; // The first error from a future. | 344 var error; // The first error from a future. |
| 322 StackTrace stackTrace; // The stackTrace that came with the error. | 345 StackTrace stackTrace; // The stackTrace that came with the error. |
| 323 | 346 |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 stackTrace = st; | 424 stackTrace = st; |
| 402 } | 425 } |
| 403 } | 426 } |
| 404 return result; | 427 return result; |
| 405 } | 428 } |
| 406 | 429 |
| 407 /** | 430 /** |
| 408 * Returns the result of the first future in [futures] to complete. | 431 * Returns the result of the first future in [futures] to complete. |
| 409 * | 432 * |
| 410 * The returned future is completed with the result of the first | 433 * The returned future is completed with the result of the first |
| 411 * future in [futures] to report that it is complete. | 434 * future in [futures] to report that it is complete, |
| 435 * whether it's with a value or an error. | |
| 412 * The results of all the other futures are discarded. | 436 * The results of all the other futures are discarded. |
| 413 * | 437 * |
| 414 * If [futures] is empty, or if none of its futures complete, | 438 * If [futures] is empty, or if none of its futures complete, |
| 415 * the returned future never completes. | 439 * the returned future never completes. |
| 416 */ | 440 */ |
| 417 static Future<T> any<T>(Iterable<Future<T>> futures) { | 441 static Future<T> any<T>(Iterable<Future<T>> futures) { |
| 418 var completer = new Completer<T>.sync(); | 442 var completer = new Completer<T>.sync(); |
| 419 var onValue = (T value) { | 443 var onValue = (T value) { |
| 420 if (!completer.isCompleted) completer.complete(value); | 444 if (!completer.isCompleted) completer.complete(value); |
| 421 }; | 445 }; |
| 422 var onError = (error, stack) { | 446 var onError = (error, stack) { |
| 423 if (!completer.isCompleted) completer.completeError(error, stack); | 447 if (!completer.isCompleted) completer.completeError(error, stack); |
| 424 }; | 448 }; |
| 425 for (var future in futures) { | 449 for (var future in futures) { |
| 426 future.then(onValue, onError: onError); | 450 future.then(onValue, onError: onError); |
| 427 } | 451 } |
| 428 return completer.future; | 452 return completer.future; |
| 429 } | 453 } |
| 430 | 454 |
| 431 /** | 455 /** |
| 432 * Perform an operation for each element of the iterable, in turn. | 456 * Performs an action for each element of the iterable, in turn. |
| 433 * | 457 * |
| 434 * The operation, [f], may be either synchronous or asynchronous. | 458 * The [action] may be either synchronous or asynchronous. |
| 435 * | 459 * |
| 436 * Calls [f] with each element in [input] in order. | 460 * Calls [action] with each element in [elements] in order. |
| 437 * If the call to [f] returns a `Future<T>`, the iteration waits | 461 * If the call to [action] returns a `Future<T>`, the iteration waits |
| 438 * until the future is completed before moving to the next element. | 462 * until the future is completed before continuing with the next element. |
| 439 * | 463 * |
| 440 * Returns a [Future] that completes with `null` when all elements have been | 464 * Returns a [Future] that completes with `null` when all elements have been |
| 441 * processed. | 465 * processed. |
| 442 * | 466 * |
| 443 * Non-[Future] return values, and completion-values of returned [Future]s, | 467 * Non-[Future] return values, and completion-values of returned [Future]s, |
| 444 * are discarded. | 468 * are discarded. |
| 445 * | 469 * |
| 446 * Any error from [f], synchronous or asynchronous, will stop the iteration | 470 * Any error from [action], synchronous or asynchronous, |
| 447 * and will be reported in the returned [Future]. | 471 * will stop the iteration and be reported in the returned [Future]. |
| 448 */ | 472 */ |
| 449 static Future forEach<T>(Iterable<T> input, FutureOr f(T element)) { | 473 static Future forEach<T>(Iterable<T> elements, FutureOr action(T element)) { |
| 450 var iterator = input.iterator; | 474 var iterator = elements.iterator; |
| 451 return doWhile(() { | 475 return doWhile(() { |
| 452 if (!iterator.moveNext()) return false; | 476 if (!iterator.moveNext()) return false; |
| 453 var result = f(iterator.current); | 477 var result = action(iterator.current); |
| 454 if (result is Future) return result.then(_kTrue); | 478 if (result is Future) return result.then(_kTrue); |
| 455 return true; | 479 return true; |
| 456 }); | 480 }); |
| 457 } | 481 } |
| 458 | 482 |
| 459 // Constant `true` function, used as callback by [forEach]. | 483 // Constant `true` function, used as callback by [forEach]. |
| 460 static bool _kTrue(_) => true; | 484 static bool _kTrue(_) => true; |
| 461 | 485 |
| 462 /** | 486 /** |
| 463 * Performs an operation repeatedly until it returns `false`. | 487 * Performs an operation repeatedly until it returns `false`. |
| 464 * | 488 * |
| 465 * The operation, [f], may be either synchronous or asynchronous. | 489 * The operation, [f], may be either synchronous or asynchronous. |
| 466 * | 490 * |
| 467 * The operation is called repeatedly as long as it returns either the [bool] | 491 * The operation is called repeatedly as long as it returns either the [bool] |
| 468 * value `true` or a `Future<bool>` which completes with the value `true`. | 492 * value `true` or a `Future<bool>` which completes with the value `true`. |
| 469 * | 493 * |
| 470 * If a call to [f] returns `false` or a [Future] that completes to `false`, | 494 * If a call to [f] returns `false` or a [Future] that completes to `false`, |
| 471 * iteration ends and the future returned by [doWhile] is completed with | 495 * iteration ends and the future returned by [doWhile] is completed with |
| 472 * a `null` value. | 496 * a `null` value. |
| 473 * | 497 * |
| 474 * If a call to [f] throws or a future returned by [f] completes with | 498 * If a call to [f] throws or a future returned by [f] completes with |
| 475 * an error, iteration ends and the future returned by [doWhile] | 499 * an error, iteration ends and the future returned by [doWhile] |
| 476 * completes with the same error. | 500 * completes with the same error. |
| 477 * | 501 * |
| 478 * Calls to [f] may happen at any time, including immediately after calling | 502 * Calls to [action] may happen at any time, |
| 479 * `doWhile`. The only restriction is a new call to [f] won't happen before | 503 * including immediately after calling `doWhile`. |
| 504 * The only restriction is a new call to [action] won't happen before | |
| 480 * the previous call has returned, and if it returned a `Future<bool>`, not | 505 * the previous call has returned, and if it returned a `Future<bool>`, not |
| 481 * until that future has completed. | 506 * until that future has completed. |
| 482 */ | 507 */ |
| 483 static Future doWhile(FutureOr<bool> f()) { | 508 static Future doWhile(FutureOr<bool> action()) { |
| 484 _Future doneSignal = new _Future(); | 509 _Future doneSignal = new _Future(); |
| 485 var nextIteration; | 510 var nextIteration; |
| 486 // Bind this callback explicitly so that each iteration isn't bound in the | 511 // Bind this callback explicitly so that each iteration isn't bound in the |
| 487 // context of all the previous iterations' callbacks. | 512 // context of all the previous iterations' callbacks. |
| 488 // This avoids, e.g., deeply nested stack traces from the stack trace | 513 // This avoids, e.g., deeply nested stack traces from the stack trace |
| 489 // package. | 514 // package. |
| 490 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) { | 515 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) { |
| 491 while (keepGoing) { | 516 while (keepGoing) { |
| 492 FutureOr<bool> result; | 517 FutureOr<bool> result; |
| 493 try { | 518 try { |
| 494 result = f(); | 519 result = action(); |
| 495 } catch (error, stackTrace) { | 520 } catch (error, stackTrace) { |
| 496 // Cannot use _completeWithErrorCallback because it completes | 521 // Cannot use _completeWithErrorCallback because it completes |
| 497 // the future synchronously. | 522 // the future synchronously. |
| 498 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); | 523 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); |
| 499 return; | 524 return; |
| 500 } | 525 } |
| 501 if (result is Future<bool>) { | 526 if (result is Future<bool>) { |
| 502 result.then(nextIteration, onError: doneSignal._completeError); | 527 result.then(nextIteration, onError: doneSignal._completeError); |
| 503 return; | 528 return; |
| 504 } | 529 } |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 582 * If `test` is omitted, it defaults to a function that always returns true. | 607 * If `test` is omitted, it defaults to a function that always returns true. |
| 583 * The `test` function should not throw, but if it does, it is handled as | 608 * The `test` function should not throw, but if it does, it is handled as |
| 584 * if the `onError` function had thrown. | 609 * if the `onError` function had thrown. |
| 585 * | 610 * |
| 586 * Note that futures don't delay reporting of errors until listeners are | 611 * Note that futures don't delay reporting of errors until listeners are |
| 587 * added. If the first `catchError` (or `then`) call happens after this future | 612 * added. If the first `catchError` (or `then`) call happens after this future |
| 588 * has completed with an error then the error is reported as unhandled error. | 613 * has completed with an error then the error is reported as unhandled error. |
| 589 * See the description on [Future]. | 614 * See the description on [Future]. |
| 590 * | 615 * |
| 591 * Example: | 616 * Example: |
| 592 * | 617 * ``` |
|
floitsch
2017/05/31 15:28:28
I would just remove this example. Way too complica
Lasse Reichstein Nielsen
2017/06/02 05:53:38
Removed.
| |
| 593 * foo | 618 * foo |
| 594 * .catchError(..., test: (e) => e is ArgumentError) | 619 * .catchError(..., test: (e) => e is ArgumentError) |
| 595 * .catchError(..., test: (e) => e is NoSuchMethodError) | 620 * .catchError(..., test: (e) => e is NoSuchMethodError) |
| 596 * .then((v) { ... }); | 621 * .then((v) { ... }); |
| 622 * ``` | |
| 597 * | 623 * |
| 598 * This method is equivalent to: | 624 * This method is equivalent to: |
| 599 * | 625 * ``` |
| 600 * Future catchError(onError(error), | 626 * Future catchError(onError(error), |
| 601 * {bool test(error)}) { | 627 * {bool test(error)}) { |
| 602 * this.then((v) => v, // Forward the value. | 628 * this.then((v) => v, // Forward the value. |
| 603 * // But handle errors, if the [test] succeeds. | 629 * // But handle errors, if the [test] succeeds. |
| 604 * onError: (e, stackTrace) { | 630 * onError: (e, stackTrace) { |
| 605 * if (test == null || test(e)) { | 631 * if (test == null || test(e)) { |
| 606 * if (onError is ZoneBinaryCallback) { | 632 * if (onError is ZoneBinaryCallback) { |
| 607 * return onError(e, stackTrace); | 633 * return onError(e, stackTrace); |
| 608 * } | 634 * } |
| 609 * return onError(e); | 635 * return onError(e); |
| 610 * } | 636 * } |
| 611 * throw e; | 637 * throw e; |
| 612 * }); | 638 * }); |
| 613 * } | 639 * } |
| 614 * | 640 * ``` |
| 615 */ | 641 */ |
| 616 // The `Function` below stands for one of two types: | 642 // The `Function` below stands for one of two types: |
| 617 // - (dynamic) -> FutureOr<T> | 643 // - (dynamic) -> FutureOr<T> |
| 618 // - (dynamic, StackTrace) -> FutureOr<T> | 644 // - (dynamic, StackTrace) -> FutureOr<T> |
| 619 // Given that there is a `test` function that is usually used to do an | 645 // Given that there is a `test` function that is usually used to do an |
| 620 // `isCheck` we should also expect functions that take a specific argument. | 646 // `isCheck` we should also expect functions that take a specific argument. |
| 621 // Note: making `catchError` return a `Future<T>` in non-strong mode could be | 647 // Note: making `catchError` return a `Future<T>` in non-strong mode could be |
| 622 // a breaking change. | 648 // a breaking change. |
| 623 Future<T> catchError(Function onError, {bool test(Object error)}); | 649 Future<T> catchError(Function onError, {bool test(Object error)}); |
| 624 | 650 |
| 625 /** | 651 /** |
| 626 * Register a function to be called when this future completes. | 652 * Registers a function to be called when this future completes. |
| 627 * | 653 * |
| 628 * The [action] function is called when this future completes, whether it | 654 * The [action] function is called when this future completes, whether it |
| 629 * does so with a value or with an error. | 655 * does so with a value or with an error. |
| 630 * | 656 * |
| 631 * This is the asynchronous equivalent of a "finally" block. | 657 * This is the asynchronous equivalent of a "finally" block. |
| 632 * | 658 * |
| 633 * The future returned by this call, `f`, will complete the same way | 659 * The future returned by this call, `f`, will complete the same way |
| 634 * as this future unless an error occurs in the [action] call, or in | 660 * as this future unless an error occurs in the [action] call, or in |
| 635 * a [Future] returned by the [action] call. If the call to [action] | 661 * a [Future] returned by the [action] call. If the call to [action] |
| 636 * does not return a future, its return value is ignored. | 662 * does not return a future, its return value is ignored. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 706 } | 732 } |
| 707 } | 733 } |
| 708 | 734 |
| 709 /** | 735 /** |
| 710 * A way to produce Future objects and to complete them later | 736 * A way to produce Future objects and to complete them later |
| 711 * with a value or error. | 737 * with a value or error. |
| 712 * | 738 * |
| 713 * Most of the time, the simplest way to create a future is to just use | 739 * Most of the time, the simplest way to create a future is to just use |
| 714 * one of the [Future] constructors to capture the result of a single | 740 * one of the [Future] constructors to capture the result of a single |
| 715 * asynchronous computation: | 741 * asynchronous computation: |
| 716 * | 742 * ``` |
| 717 * new Future(() { doSomething(); return result; }); | 743 * new Future(() { doSomething(); return result; }); |
| 718 * | 744 * ``` |
| 719 * or, if the future represents the result of a sequence of asynchronous | 745 * or, if the future represents the result of a sequence of asynchronous |
| 720 * computations, they can be chained using [Future.then] or similar functions | 746 * computations, they can be chained using [Future.then] or similar functions |
| 721 * on [Future]: | 747 * on [Future]: |
| 722 * | 748 * ``` |
| 723 * Future doStuff(){ | 749 * Future doStuff(){ |
| 724 * return someAsyncOperation().then((result) { | 750 * return someAsyncOperation().then((result) { |
| 725 * return someOtherAsyncOperation(result); | 751 * return someOtherAsyncOperation(result); |
| 726 * }); | 752 * }); |
| 727 * } | 753 * } |
| 728 * | 754 * ``` |
| 729 * If you do need to create a Future from scratch — for example, | 755 * If you do need to create a Future from scratch — for example, |
| 730 * when you're converting a callback-based API into a Future-based | 756 * when you're converting a callback-based API into a Future-based |
| 731 * one — you can use a Completer as follows: | 757 * one — you can use a Completer as follows: |
| 758 * ``` | |
| 759 * class AsyncOperation { | |
| 760 * Completer _completer = new Completer(); | |
| 732 * | 761 * |
| 733 * class AsyncOperation { | 762 * Future<T> doOperation() { |
| 734 * Completer _completer = new Completer(); | 763 * _startOperation(); |
| 764 * return _completer.future; // Send future object back to client. | |
| 765 * } | |
| 735 * | 766 * |
| 736 * Future<T> doOperation() { | 767 * // Something calls this when the value is ready. |
| 737 * _startOperation(); | 768 * void _finishOperation(T result) { |
| 738 * return _completer.future; // Send future object back to client. | 769 * _completer.complete(result); |
| 739 * } | 770 * } |
| 740 * | 771 * |
| 741 * // Something calls this when the value is ready. | 772 * // If something goes wrong, call this. |
| 742 * void _finishOperation(T result) { | 773 * void _errorHappened(error) { |
| 743 * _completer.complete(result); | 774 * _completer.completeError(error); |
| 744 * } | 775 * } |
| 745 * | 776 * } |
| 746 * // If something goes wrong, call this. | 777 * ``` |
| 747 * void _errorHappened(error) { | |
| 748 * _completer.completeError(error); | |
| 749 * } | |
| 750 * } | |
| 751 */ | 778 */ |
| 752 abstract class Completer<T> { | 779 abstract class Completer<T> { |
| 753 /** | 780 /** |
| 754 * Creates a new completer. | 781 * Creates a new completer. |
| 755 * | 782 * |
| 756 * The general workflow for creating a new future is to 1) create a | 783 * The general workflow for creating a new future is to 1) create a |
| 757 * new completer, 2) hand out its future, and, at a later point, 3) invoke | 784 * new completer, 2) hand out its future, and, at a later point, 3) invoke |
| 758 * either [complete] or [completeError]. | 785 * either [complete] or [completeError]. |
| 759 * | 786 * |
| 760 * The completer completes the future asynchronously. That means that | 787 * The completer completes the future asynchronously. That means that |
| 761 * callbacks registered on the future, are not called immediately when | 788 * callbacks registered on the future are not called immediately when |
| 762 * [complete] or [completeError] is called. Instead the callbacks are | 789 * [complete] or [completeError] is called. Instead the callbacks are |
| 763 * delayed until a later microtask. | 790 * delayed until a later microtask. |
| 764 * | 791 * |
| 765 * Example: | 792 * Example: |
| 766 * | 793 * ``` |
| 767 * var completer = new Completer(); | 794 * var completer = new Completer(); |
| 768 * handOut(completer.future); | 795 * handOut(completer.future); |
| 769 * later: { | 796 * later: { |
| 770 * completer.complete('completion value'); | 797 * completer.complete('completion value'); |
| 771 * } | 798 * } |
| 799 * ``` | |
| 772 */ | 800 */ |
| 773 factory Completer() => new _AsyncCompleter<T>(); | 801 factory Completer() => new _AsyncCompleter<T>(); |
| 774 | 802 |
| 775 /** | 803 /** |
| 776 * Completes the future synchronously. | 804 * Completes the future synchronously. |
| 777 * | 805 * |
| 778 * This constructor should be avoided unless the completion of the future is | 806 * This constructor should be avoided unless the completion of the future is |
| 779 * known to be the final result of another asynchronous operation. If in doubt | 807 * known to be the final result of another asynchronous operation. If in doubt |
| 780 * use the default [Completer] constructor. | 808 * use the default [Completer] constructor. |
| 781 * | 809 * |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 817 * // The completion is the result of the asynchronous onDone event. | 845 * // The completion is the result of the asynchronous onDone event. |
| 818 * // However, there is still code executed after the completion. This | 846 * // However, there is still code executed after the completion. This |
| 819 * // operation is *not* safe. | 847 * // operation is *not* safe. |
| 820 * stream.listen(print, onDone: () { | 848 * stream.listen(print, onDone: () { |
| 821 * completer.complete("done"); | 849 * completer.complete("done"); |
| 822 * foo(); // In this case, foo() runs after bar(). | 850 * foo(); // In this case, foo() runs after bar(). |
| 823 * }); | 851 * }); |
| 824 */ | 852 */ |
| 825 factory Completer.sync() => new _SyncCompleter<T>(); | 853 factory Completer.sync() => new _SyncCompleter<T>(); |
| 826 | 854 |
| 827 /** The future that will contain the result provided to this completer. */ | 855 /** The future completed by this completer. */ |
|
floitsch
2017/05/31 15:28:27
It's not always completed yet.
maybe?
The future
Lasse Reichstein Nielsen
2017/06/02 05:53:38
I think it can work as written. "Completed by" can
| |
| 828 Future<T> get future; | 856 Future<T> get future; |
| 829 | 857 |
| 830 /** | 858 /** |
| 831 * Completes [future] with the supplied values. | 859 * Completes [future] with the supplied values. |
| 832 * | 860 * |
| 833 * The value must be either a value of type [T] | 861 * The value must be either a value of type [T] |
| 834 * or a future of type `Future<T>`. | 862 * or a future of type `Future<T>`. |
| 835 * | 863 * |
| 836 * If the value is itself a future, the completer will wait for that future | 864 * If the value is itself a future, the completer will wait for that future |
| 837 * to complete, and complete with the same result, whether it is a success | 865 * to complete, and complete with the same result, whether it is a success |
| 838 * or an error. | 866 * or an error. |
| 839 * | 867 * |
| 840 * Calling `complete` or [completeError] must not be done more than once. | 868 * Calling [complete] or [completeError] must be done at most once. |
| 841 * | 869 * |
| 842 * All listeners on the future are informed about the value. | 870 * All listeners on the future are informed about the value. |
| 843 */ | 871 */ |
| 844 void complete([FutureOr<T> value]); | 872 void complete([FutureOr<T> value]); |
| 845 | 873 |
| 846 /** | 874 /** |
| 847 * Complete [future] with an error. | 875 * Complete [future] with an error. |
| 848 * | 876 * |
| 849 * Calling [complete] or `completeError` must not be done more than once. | 877 * Calling [complete] or [completeError] must be done at most once. |
| 850 * | 878 * |
| 851 * Completing a future with an error indicates that an exception was thrown | 879 * Completing a future with an error indicates that an exception was thrown |
| 852 * while trying to produce a value. | 880 * while trying to produce a value. |
| 853 * | 881 * |
| 854 * If [error] is `null`, it is replaced by a [NullThrownError]. | 882 * If [error] is `null`, it is replaced by a [NullThrownError]. |
| 855 * | 883 * |
| 856 * If `error` is a `Future`, the future itself is used as the error value. | 884 * If `error` is a `Future`, the future itself is used as the error value. |
| 857 * If you want to complete with the result of the future, you can use: | 885 * If you want to complete with the result of the future, you can use: |
| 858 * | 886 * ``` |
| 859 * thisCompleter.complete(theFuture) | 887 * thisCompleter.complete(theFuture) |
| 860 * | 888 * ``` |
| 861 * or if you only want to handle an error from the future: | 889 * or if you only want to handle an error from the future: |
| 862 * | 890 * ``` |
| 863 * theFuture.catchError(thisCompleter.completeError); | 891 * theFuture.catchError(thisCompleter.completeError); |
| 864 * | 892 * ``` |
| 865 */ | 893 */ |
| 866 void completeError(Object error, [StackTrace stackTrace]); | 894 void completeError(Object error, [StackTrace stackTrace]); |
| 867 | 895 |
| 868 /** | 896 /** |
| 869 * Whether the future has been completed. | 897 * Whether the [future] has been completed. |
| 898 * | |
| 899 * Actually reflects whether [complete] or [completeError] has been called. | |
|
floitsch
2017/05/31 15:28:27
Remove "Actually".
| |
| 900 * If [complete] is called with a future, the actual completion my happen | |
|
floitsch
2017/05/31 15:28:27
That sounds wrong (and I interpreted it the wrong
Lasse Reichstein Nielsen
2017/06/02 05:53:39
Reworded to something like that.
(It doesn't wait
| |
| 901 * later. | |
| 902 * | |
| 903 * When this value is `true`, [complete] and [completeError] must not be | |
| 904 * called again. | |
| 870 */ | 905 */ |
| 871 bool get isCompleted; | 906 bool get isCompleted; |
| 872 } | 907 } |
| 873 | 908 |
| 874 // Helper function completing a _Future with error, but checking the zone | 909 // Helper function completing a _Future with error, but checking the zone |
| 875 // for error replacement first. | 910 // for error replacement first. |
| 876 void _completeWithErrorCallback(_Future result, error, stackTrace) { | 911 void _completeWithErrorCallback(_Future result, error, stackTrace) { |
| 877 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); | 912 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); |
| 878 if (replacement != null) { | 913 if (replacement != null) { |
| 879 error = _nonNullError(replacement.error); | 914 error = _nonNullError(replacement.error); |
| 880 stackTrace = replacement.stackTrace; | 915 stackTrace = replacement.stackTrace; |
| 881 } | 916 } |
| 882 result._completeError(error, stackTrace); | 917 result._completeError(error, stackTrace); |
| 883 } | 918 } |
| 884 | 919 |
| 885 // Like [_completeWIthErrorCallback] but completes asynchronously. | 920 // Like [_completeWithErrorCallback] but completes asynchronously. |
| 886 void _asyncCompleteWithErrorCallback(_Future result, error, stackTrace) { | 921 void _asyncCompleteWithErrorCallback(_Future result, error, stackTrace) { |
| 887 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); | 922 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); |
| 888 if (replacement != null) { | 923 if (replacement != null) { |
| 889 error = _nonNullError(replacement.error); | 924 error = _nonNullError(replacement.error); |
| 890 stackTrace = replacement.stackTrace; | 925 stackTrace = replacement.stackTrace; |
| 891 } | 926 } |
| 892 result._asyncCompleteError(error, stackTrace); | 927 result._asyncCompleteError(error, stackTrace); |
| 893 } | 928 } |
| 894 | 929 |
| 895 /** Helper function that converts `null` to a [NullThrownError]. */ | 930 /** Helper function that converts `null` to a [NullThrownError]. */ |
| 896 Object _nonNullError(Object error) => error ?? new NullThrownError(); | 931 Object _nonNullError(Object error) => error ?? new NullThrownError(); |
| OLD | NEW |