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 /** The onValue and onError handlers return either a value or a future */ | 7 /** The onValue and onError handlers return either a value or a future */ |
8 typedef dynamic _FutureOnValue<T>(T value); | 8 typedef dynamic _FutureOnValue<T>(T value); |
9 /** Test used by [Future.catchError] to handle skip some errors. */ | 9 /** Test used by [Future.catchError] to handle skip some errors. */ |
10 typedef bool _FutureErrorTest(var error); | 10 typedef bool _FutureErrorTest(var error); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 * remaining listeners. | 121 * remaining listeners. |
122 */ | 122 */ |
123 // TODO(floitsch): since single listeners are the common case we should | 123 // TODO(floitsch): since single listeners are the common case we should |
124 // use a bit to indicate that the _resultOrListeners contains a container. | 124 // use a bit to indicate that the _resultOrListeners contains a container. |
125 _Future _nextListener; | 125 _Future _nextListener; |
126 | 126 |
127 // TODO(floitsch): we only need two closure fields to store the callbacks. | 127 // TODO(floitsch): we only need two closure fields to store the callbacks. |
128 // If we store the type of a closure in the state field (where there are | 128 // If we store the type of a closure in the state field (where there are |
129 // still bits left), we can just store two closures instead of using 4 | 129 // still bits left), we can just store two closures instead of using 4 |
130 // fields of which 2 are always null. | 130 // fields of which 2 are always null. |
131 final _FutureOnValue _onValueCallback; | 131 _FutureOnValue _onValueCallback; |
132 final _FutureErrorTest _errorTestCallback; | 132 _FutureErrorTest _errorTestCallback; |
133 final Function _onErrorCallback; | 133 Function _onErrorCallback; |
134 final _FutureAction _whenCompleteActionCallback; | 134 _FutureAction _whenCompleteActionCallback; |
135 | 135 |
136 _FutureOnValue get _onValue => _isChained ? null : _onValueCallback; | 136 _FutureOnValue get _onValue => _isChained ? null : _onValueCallback; |
137 _FutureErrorTest get _errorTest => _isChained ? null : _errorTestCallback; | 137 _FutureErrorTest get _errorTest => _isChained ? null : _errorTestCallback; |
138 Function get _onError => _isChained ? null : _onErrorCallback; | 138 Function get _onError => _isChained ? null : _onErrorCallback; |
139 _FutureAction get _whenCompleteAction | 139 _FutureAction get _whenCompleteAction |
140 => _isChained ? null : _whenCompleteActionCallback; | 140 => _isChained ? null : _whenCompleteActionCallback; |
141 | 141 |
142 _Future() | 142 _Future() |
143 : _zone = Zone.current, | 143 : _zone = Zone.current, |
144 _onValueCallback = null, _errorTestCallback = null, | 144 _onValueCallback = null, _errorTestCallback = null, |
floitsch
2014/06/17 08:56:35
There are lots of null-initializations that can be
| |
145 _onErrorCallback = null, _whenCompleteActionCallback = null; | 145 _onErrorCallback = null, _whenCompleteActionCallback = null; |
146 | 146 |
147 /// Valid types for value: `T` or `Future<T>`. | 147 /// Valid types for value: `T` or `Future<T>`. |
148 _Future.immediate(value) | 148 _Future.immediate(value) |
149 : _zone = Zone.current, | 149 : _zone = Zone.current, |
150 _onValueCallback = null, _errorTestCallback = null, | 150 _onValueCallback = null, _errorTestCallback = null, |
151 _onErrorCallback = null, _whenCompleteActionCallback = null { | 151 _onErrorCallback = null, _whenCompleteActionCallback = null { |
152 _asyncComplete(value); | 152 _asyncComplete(value); |
153 } | 153 } |
154 | 154 |
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
571 listenerHasValue = handleValueCallback(); | 571 listenerHasValue = handleValueCallback(); |
572 } | 572 } |
573 } else { | 573 } else { |
574 handleError(); | 574 handleError(); |
575 } | 575 } |
576 if (listener._whenCompleteAction != null) { | 576 if (listener._whenCompleteAction != null) { |
577 handleWhenCompleteCallback(); | 577 handleWhenCompleteCallback(); |
578 } | 578 } |
579 // If we changed zone, oldZone will not be null. | 579 // If we changed zone, oldZone will not be null. |
580 if (oldZone != null) Zone._leave(oldZone); | 580 if (oldZone != null) Zone._leave(oldZone); |
581 listener._onValueCallback = null; | |
582 listener._errorTestCallback = null; | |
583 listener._onErrorCallback = null; | |
584 listener._whenCompleteActionCallback = null; | |
581 | 585 |
582 if (isPropagationAborted) return; | 586 if (isPropagationAborted) return; |
583 // If the listener's value is a future we need to chain it. Note that | 587 // If the listener's value is a future we need to chain it. Note that |
584 // this can only happen if there is a callback. Since 'is' checks | 588 // this can only happen if there is a callback. Since 'is' checks |
585 // can be expensive, we're trying to avoid it. | 589 // can be expensive, we're trying to avoid it. |
586 if (listenerHasValue && | 590 if (listenerHasValue && |
587 !identical(sourceValue, listenerValueOrError) && | 591 !identical(sourceValue, listenerValueOrError) && |
588 listenerValueOrError is Future) { | 592 listenerValueOrError is Future) { |
589 Future chainSource = listenerValueOrError; | 593 Future chainSource = listenerValueOrError; |
590 // Shortcut if the chain-source is already completed. Just continue | 594 // Shortcut if the chain-source is already completed. Just continue |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 } | 649 } |
646 }, onError: (e, s) { | 650 }, onError: (e, s) { |
647 if (timer.isActive) { | 651 if (timer.isActive) { |
648 timer.cancel(); | 652 timer.cancel(); |
649 result._completeError(e, s); | 653 result._completeError(e, s); |
650 } | 654 } |
651 }); | 655 }); |
652 return result; | 656 return result; |
653 } | 657 } |
654 } | 658 } |
OLD | NEW |