Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: corelib/src/implementation/future_implementation.dart

Issue 10517006: Adds a callback to Future that is invoked upon completion, whether success or failure. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // Dart core library. 2 // Dart core library.
3 3
4 class FutureImpl<T> implements Future<T> { 4 class FutureImpl<T> implements Future<T> {
5 5
6 bool _isComplete = false; 6 bool _isComplete = false;
7 7
8 /** 8 /**
9 * Value that was provided to this Future by the Completer 9 * Value that was provided to this Future by the Completer
10 */ 10 */
11 T _value; 11 T _value;
12 12
13 /** 13 /**
14 * Exception that occured, if there was a problem providing 14 * Exception that occured, if there was a problem providing
15 * Value. 15 * Value.
16 */ 16 */
17 Object _exception; 17 Object _exception;
18 18
19 /** 19 /**
20 * true, if any onException handler handled the exception. 20 * true, if any onException handler handled the exception.
21 */ 21 */
22 bool _exceptionHandled = false; 22 bool _exceptionHandled = false;
23 23
24 /** 24 /**
25 * Listeners waiting to receive the value of this future. 25 * Listeners waiting to receive the value of this future.
26 */ 26 */
27 final List<Function> _listeners; 27 final List<Function> _successListeners;
28 28
29 /** 29 /**
30 * Exception handlers waiting for exceptions. 30 * Exception handlers waiting for exceptions.
31 */ 31 */
32 final List<Function> _exceptionHandlers; 32 final List<Function> _exceptionHandlers;
33 33
34 /**
35 * Listeners waiting to be called when the future completes.
36 */
37 final List<Function> _completionListeners;
38
34 FutureImpl() 39 FutureImpl()
35 : _listeners = [], 40 : _successListeners = [],
36 _exceptionHandlers = []; 41 _exceptionHandlers = [],
42 _completionListeners = [];
37 43
38 factory FutureImpl.immediate(T value) { 44 factory FutureImpl.immediate(T value) {
39 final res = new FutureImpl(); 45 final res = new FutureImpl();
40 res._setValue(value); 46 res._setValue(value);
41 return res; 47 return res;
42 } 48 }
43 49
44 T get value() { 50 T get value() {
45 if (!isComplete) { 51 if (!isComplete) {
46 throw new FutureNotCompleteException(); 52 throw new FutureNotCompleteException();
(...skipping 12 matching lines...) Expand all
59 } 65 }
60 66
61 bool get isComplete() { 67 bool get isComplete() {
62 return _isComplete; 68 return _isComplete;
63 } 69 }
64 70
65 bool get hasValue() { 71 bool get hasValue() {
66 return isComplete && _exception === null; 72 return isComplete && _exception === null;
67 } 73 }
68 74
69 void then(void onComplete(T value)) { 75 void then(void onSuccess(T value)) {
Siggi Cherem (dart-lang) 2012/06/06 20:42:49 onSuccess => onValue (to match what you had in the
70 if (hasValue) { 76 if (hasValue) {
71 onComplete(value); 77 onSuccess(value);
72 } else if (!isComplete) { 78 } else if (!isComplete) {
73 _listeners.add(onComplete); 79 _successListeners.add(onSuccess);
74 } else if (!_exceptionHandled) { 80 } else if (!_exceptionHandled) {
75 throw _exception; 81 throw _exception;
76 } 82 }
77 } 83 }
78 84
79 void handleException(bool onException(Object exception)) { 85 void handleException(bool onException(Object exception)) {
80 if (_exceptionHandled) return; 86 if (_exceptionHandled) return;
81 if (_isComplete) { 87 if (_isComplete) {
82 if (_exception != null) { 88 if (_exception != null) {
83 _exceptionHandled = onException(_exception); 89 _exceptionHandled = onException(_exception);
84 } 90 }
85 } else { 91 } else {
86 _exceptionHandlers.add(onException); 92 _exceptionHandlers.add(onException);
87 } 93 }
88 } 94 }
89 95
96 void onComplete(void complete(Future<T> future)) {
97 if (_isComplete) {
98 try {
99 complete(this);
100 } catch (final e) {}
101 } else {
102 _completionListeners.add(complete);
103 }
104 }
105
90 void _complete() { 106 void _complete() {
91 _isComplete = true; 107 _isComplete = true;
92 if (_exception !== null) { 108
93 for (Function handler in _exceptionHandlers) { 109 try {
94 // Explicitly check for true here so that if the handler returns null, 110 if (_exception !== null) {
95 // we don't get an exception in checked mode. 111 for (Function handler in _exceptionHandlers) {
96 if (handler(_exception) == true) { 112 // Explicitly check for true here so that if the handler returns null,
97 _exceptionHandled = true; 113 // we don't get an exception in checked mode.
98 break; 114 if (handler(_exception) == true) {
115 _exceptionHandled = true;
116 break;
117 }
99 } 118 }
100 } 119 }
101 }
102 120
103 if (hasValue) { 121 if (hasValue) {
104 for (Function listener in _listeners) { 122 for (Function listener in _successListeners) {
105 listener(value); 123 listener(value);
124 }
125 } else {
126 if (!_exceptionHandled && _successListeners.length > 0) {
127 throw _exception;
128 }
106 } 129 }
107 } else { 130 } finally {
108 if (!_exceptionHandled && _listeners.length > 0) { 131 for (Function listener in _completionListeners) {
109 throw _exception; 132 try {
110 } 133 listener(this);
134 } catch (final e) {}
135 }
111 } 136 }
112 } 137 }
113 138
114 void _setValue(T value) { 139 void _setValue(T value) {
115 if (_isComplete) { 140 if (_isComplete) {
116 throw new FutureAlreadyCompleteException(); 141 throw new FutureAlreadyCompleteException();
117 } 142 }
118 _value = value; 143 _value = value;
119 _complete(); 144 _complete();
120 } 145 }
121 146
122 void _setException(var exception) { 147 void _setException(var exception) {
123 if (exception === null) { 148 if (exception === null) {
124 // null is not a legal value for the exception of a Future 149 // null is not a legal value for the exception of a Future
125 throw new IllegalArgumentException(null); 150 throw new IllegalArgumentException(null);
126 } 151 }
127 if (_isComplete) { 152 if (_isComplete) {
128 throw new FutureAlreadyCompleteException(); 153 throw new FutureAlreadyCompleteException();
129 } 154 }
130 _exception = exception; 155 _exception = exception;
131 _complete(); 156 _complete();
132 } 157 }
133 158
134 Future transform(Function transformation) { 159 Future transform(Function transformation) {
135 final completer = new Completer(); 160 final completer = new Completer();
136 handleException((e) { 161 onComplete((f) {
137 completer.completeException(e); 162 if (!f.hasValue) {
138 return true; 163 completer.completeException(f.exception);
139 }); 164 return;
140 then((v) { 165 }
141 var transformed = null; 166 var transformed = null;
142 try { 167 try {
143 transformed = transformation(v); 168 transformed = transformation(f.value);
144 } catch (final e) { 169 } catch (final e) {
145 completer.completeException(e); 170 completer.completeException(e);
146 return; 171 return;
147 } 172 }
148 completer.complete(transformed); 173 completer.complete(transformed);
149 }); 174 });
150 return completer.future; 175 return completer.future;
151 } 176 }
152 177
153 Future chain(Function transformation) { 178 Future chain(Function transformation) {
154 final completer = new Completer(); 179 final completer = new Completer();
155 handleException((e) { 180 onComplete((f) {
156 completer.completeException(e); 181 if (!f.hasValue) {
157 return true; 182 completer.completeException(f.exception);
158 }); 183 return;
159 then((v) { 184 }
160 var future = null; 185 var future = null;
161 try { 186 try {
162 future = transformation(v); 187 future = transformation(f.value);
163 } catch (final e) { 188 } catch (final e) {
164 completer.completeException(e); 189 completer.completeException(e);
165 return; 190 return;
166 } 191 }
167 future.handleException((e) { 192 future.onComplete((g) => g.hasValue
168 completer.completeException(e); 193 ? completer.complete(g.value)
169 return true; 194 : completer.completeException(g.exception));
170 });
171 future.then((b) => completer.complete(b));
172 }); 195 });
173 return completer.future; 196 return completer.future;
174 } 197 }
175 } 198 }
176 199
177 class CompleterImpl<T> implements Completer<T> { 200 class CompleterImpl<T> implements Completer<T> {
178 201
179 final FutureImpl<T> _futureImpl; 202 final FutureImpl<T> _futureImpl;
180 203
181 CompleterImpl() : _futureImpl = new FutureImpl() {} 204 CompleterImpl() : _futureImpl = new FutureImpl() {}
182 205
183 Future<T> get future() { 206 Future<T> get future() {
184 return _futureImpl; 207 return _futureImpl;
185 } 208 }
186 209
187 void complete(T value) { 210 void complete(T value) {
188 _futureImpl._setValue(value); 211 _futureImpl._setValue(value);
189 } 212 }
190 213
191 void completeException(var exception) { 214 void completeException(var exception) {
192 _futureImpl._setException(exception); 215 _futureImpl._setException(exception);
193 } 216 }
194 } 217 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698