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