OLD | NEW |
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 * Stack trace associated with [_exception], if one was provided. | 20 * Stack trace associated with [_exception], if one was provided. |
21 */ | 21 */ |
22 Object _stackTrace; | 22 Object _stackTrace; |
23 | 23 |
24 /** | 24 /** |
25 * true, if any onException handler handled the exception. | 25 * true, if any onException handler handled the exception. |
26 */ | 26 */ |
27 bool _exceptionHandled = false; | 27 bool _exceptionHandled = false; |
28 | 28 |
29 /** | 29 /** |
| 30 * true if an exception in this future should be thrown to the top level. |
| 31 */ |
| 32 bool _throwOnException = false; |
| 33 |
| 34 /** |
30 * Listeners waiting to receive the value of this future. | 35 * Listeners waiting to receive the value of this future. |
31 */ | 36 */ |
32 final List<Function> _successListeners; | 37 final List<Function> _successListeners; |
33 | 38 |
34 /** | 39 /** |
35 * Exception handlers waiting for exceptions. | 40 * Exception handlers waiting for exceptions. |
36 */ | 41 */ |
37 final List<Function> _exceptionHandlers; | 42 final List<Function> _exceptionHandlers; |
38 | 43 |
39 /** | 44 /** |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 } | 86 } |
82 | 87 |
83 bool get hasValue { | 88 bool get hasValue { |
84 return isComplete && _exception == null; | 89 return isComplete && _exception == null; |
85 } | 90 } |
86 | 91 |
87 void then(void onSuccess(T value)) { | 92 void then(void onSuccess(T value)) { |
88 if (hasValue) { | 93 if (hasValue) { |
89 onSuccess(value); | 94 onSuccess(value); |
90 } else if (!isComplete) { | 95 } else if (!isComplete) { |
| 96 _throwOnException = true; |
91 _successListeners.add(onSuccess); | 97 _successListeners.add(onSuccess); |
92 } else if (!_exceptionHandled) { | 98 } else if (!_exceptionHandled) { |
93 throw new FutureUnhandledException(_exception, stackTrace); | 99 throw new FutureUnhandledException(_exception, stackTrace); |
94 } | 100 } |
95 } | 101 } |
96 | 102 |
| 103 void _handleSuccess(void onSuccess(T value)) { |
| 104 if (hasValue) { |
| 105 onSuccess(value); |
| 106 } else if (!isComplete) { |
| 107 _successListeners.add(onSuccess); |
| 108 } |
| 109 } |
| 110 |
97 void handleException(bool onException(Object exception)) { | 111 void handleException(bool onException(Object exception)) { |
98 if (_exceptionHandled) return; | 112 if (_exceptionHandled) return; |
99 if (_isComplete) { | 113 if (_isComplete) { |
100 if (_exception != null) { | 114 if (_exception != null) { |
101 _exceptionHandled = onException(_exception); | 115 _exceptionHandled = onException(_exception); |
102 } | 116 } |
103 } else { | 117 } else { |
104 _exceptionHandlers.add(onException); | 118 _exceptionHandlers.add(onException); |
105 } | 119 } |
106 } | 120 } |
(...skipping 21 matching lines...) Expand all Loading... |
128 break; | 142 break; |
129 } | 143 } |
130 } | 144 } |
131 } | 145 } |
132 | 146 |
133 if (hasValue) { | 147 if (hasValue) { |
134 for (Function listener in _successListeners) { | 148 for (Function listener in _successListeners) { |
135 listener(value); | 149 listener(value); |
136 } | 150 } |
137 } else { | 151 } else { |
138 if (!_exceptionHandled && _successListeners.length > 0) { | 152 if (!_exceptionHandled && _throwOnException) { |
139 throw new FutureUnhandledException(_exception, stackTrace); | 153 throw new FutureUnhandledException(_exception, stackTrace); |
140 } | 154 } |
141 } | 155 } |
142 } finally { | 156 } finally { |
143 for (Function listener in _completionListeners) { | 157 for (Function listener in _completionListeners) { |
144 try { | 158 try { |
145 listener(this); | 159 listener(this); |
146 } catch (e) {} | 160 } catch (e) {} |
147 } | 161 } |
148 } | 162 } |
(...skipping 18 matching lines...) Expand all Loading... |
167 _exception = exception; | 181 _exception = exception; |
168 _stackTrace = stackTrace; | 182 _stackTrace = stackTrace; |
169 _complete(); | 183 _complete(); |
170 } | 184 } |
171 | 185 |
172 Future transform(Function transformation) { | 186 Future transform(Function transformation) { |
173 final completer = new Completer(); | 187 final completer = new Completer(); |
174 | 188 |
175 _forwardException(this, completer); | 189 _forwardException(this, completer); |
176 | 190 |
177 then((v) { | 191 _handleSuccess((v) { |
178 var transformed = null; | 192 var transformed = null; |
179 try { | 193 try { |
180 transformed = transformation(v); | 194 transformed = transformation(v); |
181 } catch (e, stackTrace) { | 195 } catch (e, stackTrace) { |
182 completer.completeException(e, stackTrace); | 196 completer.completeException(e, stackTrace); |
183 return; | 197 return; |
184 } | 198 } |
185 completer.complete(transformed); | 199 completer.complete(transformed); |
186 }); | 200 }); |
187 | 201 |
188 return completer.future; | 202 return completer.future; |
189 } | 203 } |
190 | 204 |
191 Future chain(Function transformation) { | 205 Future chain(Function transformation) { |
192 final completer = new Completer(); | 206 final completer = new Completer(); |
193 | 207 |
194 _forwardException(this, completer); | 208 _forwardException(this, completer); |
195 then((v) { | 209 _handleSuccess((v) { |
196 var future = null; | 210 var future = null; |
197 try { | 211 try { |
198 future = transformation(v); | 212 future = transformation(v); |
199 } catch (ex, stackTrace) { | 213 } catch (ex, stackTrace) { |
200 completer.completeException(ex, stackTrace); | 214 completer.completeException(ex, stackTrace); |
201 return; | 215 return; |
202 } | 216 } |
203 | 217 |
204 _forward(future, completer); | 218 _forward(future, completer); |
205 }); | 219 }); |
(...skipping 10 matching lines...) Expand all Loading... |
216 // If the transformation itself returns a future, then we will | 230 // If the transformation itself returns a future, then we will |
217 // complete to what that completes to. | 231 // complete to what that completes to. |
218 if (result is Future) { | 232 if (result is Future) { |
219 _forward(result, completer); | 233 _forward(result, completer); |
220 } else { | 234 } else { |
221 completer.complete(result); | 235 completer.complete(result); |
222 } | 236 } |
223 } catch (innerException, stackTrace) { | 237 } catch (innerException, stackTrace) { |
224 completer.completeException(innerException, stackTrace); | 238 completer.completeException(innerException, stackTrace); |
225 } | 239 } |
226 return true; | 240 return false; |
227 }); | 241 }); |
228 | 242 |
229 then(completer.complete); | 243 _handleSuccess(completer.complete); |
230 | 244 |
231 return completer.future; | 245 return completer.future; |
232 } | 246 } |
233 | 247 |
234 /** | 248 /** |
235 * Forwards the success or error completion from [future] to [completer]. | 249 * Forwards the success or error completion from [future] to [completer]. |
236 */ | 250 */ |
237 _forward(Future future, Completer completer) { | 251 _forward(Future future, Completer completer) { |
238 _forwardException(future, completer); | 252 _forwardException(future, completer); |
239 future.then(completer.complete); | 253 future._handleSuccess(completer.complete); |
240 } | 254 } |
241 | 255 |
242 /** | 256 /** |
243 * Forwards the exception completion from [future] to [completer]. | 257 * Forwards the exception completion from [future] to [completer]. |
244 */ | 258 */ |
245 _forwardException(Future future, Completer completer) { | 259 _forwardException(Future future, Completer completer) { |
246 future.handleException((e) { | 260 future.handleException((e) { |
247 completer.completeException(e, future.stackTrace); | 261 completer.completeException(e, future.stackTrace); |
248 return true; | 262 return false; |
249 }); | 263 }); |
250 } | 264 } |
251 } | 265 } |
252 | 266 |
253 class _CompleterImpl<T> implements Completer<T> { | 267 class _CompleterImpl<T> implements Completer<T> { |
254 | 268 |
255 final _FutureImpl<T> _futureImpl; | 269 final _FutureImpl<T> _futureImpl; |
256 | 270 |
257 _CompleterImpl() : _futureImpl = new _FutureImpl() {} | 271 _CompleterImpl() : _futureImpl = new _FutureImpl() {} |
258 | 272 |
259 Future<T> get future { | 273 Future<T> get future { |
260 return _futureImpl; | 274 return _futureImpl; |
261 } | 275 } |
262 | 276 |
263 void complete(T value) { | 277 void complete(T value) { |
264 _futureImpl._setValue(value); | 278 _futureImpl._setValue(value); |
265 } | 279 } |
266 | 280 |
267 void completeException(Object exception, [Object stackTrace]) { | 281 void completeException(Object exception, [Object stackTrace]) { |
268 _futureImpl._setException(exception, stackTrace); | 282 _futureImpl._setException(exception, stackTrace); |
269 } | 283 } |
270 } | 284 } |
271 | 285 |
OLD | NEW |