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 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 * 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 |
513 * until that future has completed. | 513 * until that future has completed. |
514 */ | 514 */ |
515 static Future doWhile(FutureOr<bool> action()) { | 515 static Future doWhile(FutureOr<bool> action()) { |
516 _Future doneSignal = new _Future(); | 516 _Future doneSignal = new _Future(); |
517 var nextIteration; | 517 var nextIteration; |
518 // 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 |
519 // context of all the previous iterations' callbacks. | 519 // context of all the previous iterations' callbacks. |
520 // 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 |
521 // package. | 521 // package. |
522 nextIteration = Zone.current.bindUnaryCallbackGuarded((bool keepGoing) { | 522 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) { |
523 while (keepGoing) { | 523 while (keepGoing) { |
524 FutureOr<bool> result; | 524 FutureOr<bool> result; |
525 try { | 525 try { |
526 result = action(); | 526 result = action(); |
527 } catch (error, stackTrace) { | 527 } catch (error, stackTrace) { |
528 // Cannot use _completeWithErrorCallback because it completes | 528 // Cannot use _completeWithErrorCallback because it completes |
529 // the future synchronously. | 529 // the future synchronously. |
530 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); | 530 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); |
531 return; | 531 return; |
532 } | 532 } |
533 if (result is Future<bool>) { | 533 if (result is Future<bool>) { |
534 result.then(nextIteration, onError: doneSignal._completeError); | 534 result.then(nextIteration, onError: doneSignal._completeError); |
535 return; | 535 return; |
536 } | 536 } |
537 keepGoing = result; | 537 keepGoing = result; |
538 } | 538 } |
539 doneSignal._complete(null); | 539 doneSignal._complete(null); |
540 }); | 540 }, runGuarded: true); |
541 nextIteration(true); | 541 nextIteration(true); |
542 return doneSignal; | 542 return doneSignal; |
543 } | 543 } |
544 | 544 |
545 /** | 545 /** |
546 * Register callbacks to be called when this future completes. | 546 * Register callbacks to be called when this future completes. |
547 * | 547 * |
548 * When this future completes with a value, | 548 * When this future completes with a value, |
549 * the [onValue] callback will be called with that value. | 549 * the [onValue] callback will be called with that value. |
550 * If this future is already completed, the callback will not be called | 550 * If this future is already completed, the callback will not be called |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); | 909 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); |
910 if (replacement != null) { | 910 if (replacement != null) { |
911 error = _nonNullError(replacement.error); | 911 error = _nonNullError(replacement.error); |
912 stackTrace = replacement.stackTrace; | 912 stackTrace = replacement.stackTrace; |
913 } | 913 } |
914 result._asyncCompleteError(error, stackTrace); | 914 result._asyncCompleteError(error, stackTrace); |
915 } | 915 } |
916 | 916 |
917 /** Helper function that converts `null` to a [NullThrownError]. */ | 917 /** Helper function that converts `null` to a [NullThrownError]. */ |
918 Object _nonNullError(Object error) => error ?? new NullThrownError(); | 918 Object _nonNullError(Object error) => error ?? new NullThrownError(); |
OLD | NEW |