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

Side by Side Diff: sdk/lib/async/future_impl.dart

Issue 14251006: Remove AsyncError with Expando. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 7 years, 8 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
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 deprecatedFutureValue(_FutureImpl future) => 7 deprecatedFutureValue(_FutureImpl future) =>
8 future._isComplete ? future._resultOrListeners : null; 8 future._isComplete ? future._resultOrListeners : null;
9 9
10
11 class _CompleterImpl<T> implements Completer<T> { 10 class _CompleterImpl<T> implements Completer<T> {
12 final Future<T> future; 11 final Future<T> future;
13 bool _isComplete = false; 12 bool _isComplete = false;
14 13
15 _CompleterImpl() : future = new _FutureImpl<T>(); 14 _CompleterImpl() : future = new _FutureImpl<T>();
16 15
17 void complete([T value]) { 16 void complete([T value]) {
18 if (_isComplete) throw new StateError("Future already completed"); 17 if (_isComplete) throw new StateError("Future already completed");
19 _isComplete = true; 18 _isComplete = true;
20 _FutureImpl future = this.future; 19 _FutureImpl future = this.future;
21 future._setValue(value); 20 future._setValue(value);
22 } 21 }
23 22
24 void completeError(Object error, [Object stackTrace = null]) { 23 void completeError(Object error, [Object stackTrace = null]) {
25 if (_isComplete) throw new StateError("Future already completed"); 24 if (_isComplete) throw new StateError("Future already completed");
26 _isComplete = true; 25 _isComplete = true;
27 AsyncError asyncError; 26 if (stackTrace != null) {
28 if (error is AsyncError) { 27 // Force the stack trace onto the error, even if it already had one.
29 asyncError = error; 28 _attachStackTrace(error, stackTrace);
30 } else {
31 asyncError = new AsyncError(error, stackTrace);
32 } 29 }
33 _FutureImpl future = this.future; 30 _FutureImpl future = this.future;
34 future._setError(asyncError); 31 future._setError(error);
35 } 32 }
36 33
37 bool get isCompleted => _isComplete; 34 bool get isCompleted => _isComplete;
38 } 35 }
39 36
40 /** 37 /**
41 * A listener on a future. 38 * A listener on a future.
42 * 39 *
43 * When the future completes, the [_sendValue] or [_sendError] method 40 * When the future completes, the [_sendValue] or [_sendError] method
44 * is invoked with the result. 41 * is invoked with the result.
45 * 42 *
46 * Listeners are kept in a linked list. 43 * Listeners are kept in a linked list.
47 */ 44 */
48 abstract class _FutureListener<T> { 45 abstract class _FutureListener<T> {
49 _FutureListener _nextListener; 46 _FutureListener _nextListener;
50 factory _FutureListener.wrap(_FutureImpl future) { 47 factory _FutureListener.wrap(_FutureImpl future) {
51 return new _FutureListenerWrapper(future); 48 return new _FutureListenerWrapper(future);
52 } 49 }
53 void _sendValue(T value); 50 void _sendValue(T value);
54 void _sendError(AsyncError error); 51 void _sendError(error);
55 } 52 }
56 53
57 /** Adapter for a [_FutureImpl] to be a future result listener. */ 54 /** Adapter for a [_FutureImpl] to be a future result listener. */
58 class _FutureListenerWrapper<T> implements _FutureListener<T> { 55 class _FutureListenerWrapper<T> implements _FutureListener<T> {
59 _FutureImpl future; 56 _FutureImpl future;
60 _FutureListener _nextListener; 57 _FutureListener _nextListener;
61 _FutureListenerWrapper(this.future); 58 _FutureListenerWrapper(this.future);
62 _sendValue(T value) { future._setValue(value); } 59 _sendValue(T value) { future._setValue(value); }
63 _sendError(AsyncError error) { future._setError(error); } 60 _sendError(error) { future._setError(error); }
64 } 61 }
65 62
66 class _FutureImpl<T> implements Future<T> { 63 class _FutureImpl<T> implements Future<T> {
67 static const int _INCOMPLETE = 0; 64 static const int _INCOMPLETE = 0;
68 static const int _VALUE = 1; 65 static const int _VALUE = 1;
69 static const int _ERROR = 2; 66 static const int _ERROR = 2;
70 static const int _UNHANDLED_ERROR = 4; 67 static const int _UNHANDLED_ERROR = 4;
71 68
72 /** Whether the future is complete, and as what. */ 69 /** Whether the future is complete, and as what. */
73 int _state = _INCOMPLETE; 70 int _state = _INCOMPLETE;
74 71
75 bool get _isComplete => _state != _INCOMPLETE; 72 bool get _isComplete => _state != _INCOMPLETE;
76 bool get _hasValue => _state == _VALUE; 73 bool get _hasValue => _state == _VALUE;
77 bool get _hasError => (_state & _ERROR) != 0; 74 bool get _hasError => (_state & _ERROR) != 0;
78 bool get _hasUnhandledError => (_state & _UNHANDLED_ERROR) != 0; 75 bool get _hasUnhandledError => (_state & _UNHANDLED_ERROR) != 0;
79 76
80 void _clearUnhandledError() { 77 void _clearUnhandledError() {
81 // Works because _UNHANDLED_ERROR is highest bit in use. 78 // Works because _UNHANDLED_ERROR is highest bit in use.
82 _state &= ~_UNHANDLED_ERROR; 79 _state &= ~_UNHANDLED_ERROR;
83 } 80 }
84 81
85 /** 82 /**
86 * Either the result, or a list of listeners until the future completes. 83 * Either the result, or a list of listeners until the future completes.
87 * 84 *
88 * The result of the future is either a value or an [AsyncError]. 85 * The result of the future is either a value or an error.
89 * A result is only stored when the future has completed. 86 * A result is only stored when the future has completed.
90 * 87 *
91 * The listeners is an internally linked list of [_FutureListener]s. 88 * The listeners is an internally linked list of [_FutureListener]s.
92 * Listeners are only remembered while the future is not yet complete. 89 * Listeners are only remembered while the future is not yet complete.
93 * 90 *
94 * Since the result and the listeners cannot occur at the same time, 91 * Since the result and the listeners cannot occur at the same time,
95 * we can use the same field for both. 92 * we can use the same field for both.
96 */ 93 */
97 var _resultOrListeners; 94 var _resultOrListeners;
98 95
99 _FutureImpl(); 96 _FutureImpl();
100 97
101 _FutureImpl.immediate(T value) { 98 _FutureImpl.immediate(T value) {
102 _state = _VALUE; 99 _state = _VALUE;
103 _resultOrListeners = value; 100 _resultOrListeners = value;
104 } 101 }
105 102
106 _FutureImpl.immediateError(var error, [Object stackTrace]) { 103 _FutureImpl.immediateError(var error, [Object stackTrace]) {
107 AsyncError asyncError; 104 if (stackTrace != null) {
108 if (error is AsyncError) { 105 // Force stack trace onto error, even if it had already one.
109 asyncError = error; 106 _attachStackTrace(error, stackTrace);
110 } else {
111 asyncError = new AsyncError(error, stackTrace);
112 } 107 }
113 _setError(asyncError); 108 _setError(error);
114 } 109 }
115 110
116 factory _FutureImpl.wait(Iterable<Future> futures) { 111 factory _FutureImpl.wait(Iterable<Future> futures) {
117 Completer completer; 112 Completer completer;
118 // List collecting values from the futures. 113 // List collecting values from the futures.
119 // Set to null if an error occurs. 114 // Set to null if an error occurs.
120 List values; 115 List values;
121 void handleError(error) { 116 void handleError(error) {
122 if (values != null) { 117 if (values != null) {
123 values = null; 118 values = null;
124 completer.completeError(error.error, error.stackTrace); 119 completer.completeError(error);
125 } 120 }
126 } 121 }
127 // As each future completes, put its value into the corresponding 122 // As each future completes, put its value into the corresponding
128 // position in the list of values. 123 // position in the list of values.
129 int remaining = 0; 124 int remaining = 0;
130 for (Future future in futures) { 125 for (Future future in futures) {
131 int pos = remaining++; 126 int pos = remaining++;
132 future.catchError(handleError).then((Object value) { 127 future.catchError(handleError).then((Object value) {
133 if (values == null) return null; 128 if (values == null) return null;
134 values[pos] = value; 129 values[pos] = value;
135 remaining--; 130 remaining--;
136 if (remaining == 0) { 131 if (remaining == 0) {
137 completer.complete(values); 132 completer.complete(values);
138 } 133 }
139 }); 134 });
140 } 135 }
141 if (remaining == 0) { 136 if (remaining == 0) {
142 return new Future.immediate(const []); 137 return new Future.immediate(const []);
143 } 138 }
144 values = new List(remaining); 139 values = new List(remaining);
145 completer = new Completer<List>(); 140 completer = new Completer<List>();
146 return completer.future; 141 return completer.future;
147 } 142 }
148 143
149 Future then(f(T value), { onError(AsyncError error) }) { 144 Future then(f(T value), { onError(error) }) {
150 if (!_isComplete) { 145 if (!_isComplete) {
151 if (onError == null) { 146 if (onError == null) {
152 return new _ThenFuture(f).._subscribeTo(this); 147 return new _ThenFuture(f).._subscribeTo(this);
153 } 148 }
154 return new _SubscribeFuture(f, onError).._subscribeTo(this); 149 return new _SubscribeFuture(f, onError).._subscribeTo(this);
155 } 150 }
156 if (_hasError) { 151 if (_hasError) {
157 if (onError != null) { 152 if (onError != null) {
158 return _handleError(onError, null); 153 return _handleError(onError, null);
159 } 154 }
160 // The "f" funtion will never be called, so just return 155 // The "f" funtion will never be called, so just return
161 // a future that delegates to this. We don't want to return 156 // a future that delegates to this. We don't want to return
162 // this itself to give a signal that the future is complete. 157 // this itself to give a signal that the future is complete.
163 return new _FutureWrapper(this); 158 return new _FutureWrapper(this);
164 } else { 159 } else {
165 assert(_hasValue); 160 assert(_hasValue);
166 return _handleValue(f); 161 return _handleValue(f);
167 } 162 }
168 } 163 }
169 164
170 Future catchError(f(AsyncError asyncError), { bool test(error) }) { 165 Future catchError(f(error), { bool test(error) }) {
171 if (_hasValue) { 166 if (_hasValue) {
172 return new _FutureWrapper(this); 167 return new _FutureWrapper(this);
173 } 168 }
174 if (!_isComplete) { 169 if (!_isComplete) {
175 return new _CatchErrorFuture(f, test).._subscribeTo(this); 170 return new _CatchErrorFuture(f, test).._subscribeTo(this);
176 } else { 171 } else {
177 return _handleError(f, test); 172 return _handleError(f, test);
178 } 173 }
179 } 174 }
180 175
181 Future<T> whenComplete(action()) { 176 Future<T> whenComplete(action()) {
182 _WhenFuture<T> whenFuture = new _WhenFuture<T>(action); 177 _WhenFuture<T> whenFuture = new _WhenFuture<T>(action);
183 if (!_isComplete) { 178 if (!_isComplete) {
184 _addListener(whenFuture); 179 _addListener(whenFuture);
185 } else if (_hasValue) { 180 } else if (_hasValue) {
186 T value = _resultOrListeners; 181 T value = _resultOrListeners;
187 Timer.run(() { 182 Timer.run(() {
188 whenFuture._sendValue(value); 183 whenFuture._sendValue(value);
189 }); 184 });
190 } else { 185 } else {
191 assert(_hasError); 186 assert(_hasError);
192 _clearUnhandledError(); 187 _clearUnhandledError();
193 AsyncError error = _resultOrListeners; 188 var error = _resultOrListeners;
194 Timer.run(() { 189 Timer.run(() {
195 whenFuture._sendError(error); 190 whenFuture._sendError(error);
196 }); 191 });
197 } 192 }
198 return whenFuture; 193 return whenFuture;
199 } 194 }
200 195
201 /** Handle a late listener on a completed future with a value. */ 196 /** Handle a late listener on a completed future with a value. */
202 Future _handleValue(onValue(var value)) { 197 Future _handleValue(onValue(var value)) {
203 assert(_hasValue); 198 assert(_hasValue);
204 _ThenFuture thenFuture = new _ThenFuture(onValue); 199 _ThenFuture thenFuture = new _ThenFuture(onValue);
205 T value = _resultOrListeners; 200 T value = _resultOrListeners;
206 Timer.run(() { thenFuture._sendValue(value); }); 201 Timer.run(() { thenFuture._sendValue(value); });
207 return thenFuture; 202 return thenFuture;
208 } 203 }
209 204
210 /** Handle a late listener on a completed future with an error. */ 205 /** Handle a late listener on a completed future with an error. */
211 Future _handleError(onError(AsyncError error), bool test(error)) { 206 Future _handleError(onError(error), bool test(error)) {
212 assert(_hasError); 207 assert(_hasError);
213 _clearUnhandledError(); 208 _clearUnhandledError();
214 AsyncError error = _resultOrListeners; 209 var error = _resultOrListeners;
215 _CatchErrorFuture errorFuture = new _CatchErrorFuture(onError, test); 210 _CatchErrorFuture errorFuture = new _CatchErrorFuture(onError, test);
216 Timer.run(() { errorFuture._sendError(error); }); 211 Timer.run(() { errorFuture._sendError(error); });
217 return errorFuture; 212 return errorFuture;
218 } 213 }
219 214
220 Stream<T> asStream() => new Stream.fromFuture(this); 215 Stream<T> asStream() => new Stream.fromFuture(this);
221 216
222 void _setValue(T value) { 217 void _setValue(T value) {
223 if (_isComplete) throw new StateError("Future already completed"); 218 if (_isComplete) throw new StateError("Future already completed");
224 _FutureListener listeners = _removeListeners(); 219 _FutureListener listeners = _removeListeners();
225 _state = _VALUE; 220 _state = _VALUE;
226 _resultOrListeners = value; 221 _resultOrListeners = value;
227 while (listeners != null) { 222 while (listeners != null) {
228 _FutureListener listener = listeners; 223 _FutureListener listener = listeners;
229 listeners = listener._nextListener; 224 listeners = listener._nextListener;
230 listener._nextListener = null; 225 listener._nextListener = null;
231 listener._sendValue(value); 226 listener._sendValue(value);
232 } 227 }
233 } 228 }
234 229
235 void _setError(AsyncError error) { 230 void _setError(error) {
236 if (_isComplete) throw new StateError("Future already completed"); 231 if (_isComplete) throw new StateError("Future already completed");
237 _FutureListener listeners = _removeListeners(); 232 _FutureListener listeners = _removeListeners();
238 _state = _ERROR; 233 _state = _ERROR;
239 _resultOrListeners = error; 234 _resultOrListeners = error;
240 if (listeners == null) { 235 if (listeners == null) {
241 _scheduleUnhandledError(); 236 _scheduleUnhandledError();
242 return; 237 return;
243 } 238 }
244 do { 239 do {
245 _FutureListener listener = listeners; 240 _FutureListener listener = listeners;
246 listeners = listener._nextListener; 241 listeners = listener._nextListener;
247 listener._nextListener = null; 242 listener._nextListener = null;
248 listener._sendError(error); 243 listener._sendError(error);
249 } while (listeners != null); 244 } while (listeners != null);
250 } 245 }
251 246
252 void _scheduleUnhandledError() { 247 void _scheduleUnhandledError() {
253 _state |= _UNHANDLED_ERROR; 248 _state |= _UNHANDLED_ERROR;
254 // Wait for the rest of the current event's duration to see 249 // Wait for the rest of the current event's duration to see
255 // if a subscriber is added to handle the error. 250 // if a subscriber is added to handle the error.
256 Timer.run(() { 251 Timer.run(() {
257 if (_hasUnhandledError) { 252 if (_hasUnhandledError) {
258 // No error handler has been added since the error was set. 253 // No error handler has been added since the error was set.
259 _clearUnhandledError(); 254 _clearUnhandledError();
260 AsyncError error = _resultOrListeners; 255 var error = _resultOrListeners;
261 print("Uncaught Error: ${error.error}"); 256 print("Uncaught Error: ${error}");
262 if (error.stackTrace != null) { 257 var trace = getAttachedStackTrace(error);
263 print("Stack Trace:\n${error.stackTrace}\n"); 258 if (trace != null) {
259 print("Stack Trace:\n$trace\n");
264 } 260 }
265 throw error.error; 261 throw error;
266 } 262 }
267 }); 263 });
268 } 264 }
269 265
270 void _addListener(_FutureListener listener) { 266 void _addListener(_FutureListener listener) {
271 assert(!_isComplete); 267 assert(!_isComplete);
272 assert(listener._nextListener == null); 268 assert(listener._nextListener == null);
273 listener._nextListener = _resultOrListeners; 269 listener._nextListener = _resultOrListeners;
274 _resultOrListeners = listener; 270 _resultOrListeners = listener;
275 } 271 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 * Subclasses override [_sendValue]/[_sendError] to intercept 340 * Subclasses override [_sendValue]/[_sendError] to intercept
345 * the results of a previous future. 341 * the results of a previous future.
346 */ 342 */
347 abstract class _TransformFuture<S, T> extends _FutureImpl<T> 343 abstract class _TransformFuture<S, T> extends _FutureImpl<T>
348 implements _FutureListener<S> { 344 implements _FutureListener<S> {
349 // _FutureListener implementation. 345 // _FutureListener implementation.
350 _FutureListener _nextListener; 346 _FutureListener _nextListener;
351 347
352 void _sendValue(S value); 348 void _sendValue(S value);
353 349
354 void _sendError(AsyncError error); 350 void _sendError(error);
355 351
356 void _subscribeTo(_FutureImpl future) { 352 void _subscribeTo(_FutureImpl future) {
357 future._addListener(this); 353 future._addListener(this);
358 } 354 }
359 } 355 }
360 356
361 /** The onValue and onError handlers return either a value or a future */ 357 /** The onValue and onError handlers return either a value or a future */
362 typedef dynamic _FutureOnValue<T>(T value); 358 typedef dynamic _FutureOnValue<T>(T value);
363 typedef dynamic _FutureOnError(AsyncError error); 359 typedef dynamic _FutureOnError(error);
364 /** Test used by [Future.catchError] to handle skip some errors. */ 360 /** Test used by [Future.catchError] to handle skip some errors. */
365 typedef bool _FutureErrorTest(var error); 361 typedef bool _FutureErrorTest(var error);
366 /** Used by [WhenFuture]. */ 362 /** Used by [WhenFuture]. */
367 typedef _FutureAction(); 363 typedef _FutureAction();
368 364
369 /** Future returned by [Future.then] with no [:onError:] parameter. */ 365 /** Future returned by [Future.then] with no [:onError:] parameter. */
370 class _ThenFuture<S, T> extends _TransformFuture<S, T> { 366 class _ThenFuture<S, T> extends _TransformFuture<S, T> {
371 // TODO(ahe): Restore type when feature is implemented in dart2js 367 // TODO(ahe): Restore type when feature is implemented in dart2js
372 // checked mode. 368 // checked mode.
373 final /* _FutureOnValue<S> */ _onValue; 369 final /* _FutureOnValue<S> */ _onValue;
374 370
375 _ThenFuture(this._onValue); 371 _ThenFuture(this._onValue);
376 372
377 _sendValue(S value) { 373 _sendValue(S value) {
378 assert(_onValue != null); 374 assert(_onValue != null);
379 var result; 375 var result;
380 try { 376 try {
381 result = _onValue(value); 377 result = _onValue(value);
382 } on AsyncError catch (e) {
383 _setError(e);
384 return;
385 } catch (e, s) { 378 } catch (e, s) {
386 _setError(new AsyncError(e, s)); 379 _setError(_asyncError(e, s));
387 return; 380 return;
388 } 381 }
389 _setOrChainValue(result); 382 _setOrChainValue(result);
390 } 383 }
391 384
392 void _sendError(AsyncError error) { 385 void _sendError(error) {
393 _setError(error); 386 _setError(error);
394 } 387 }
395 } 388 }
396 389
397 /** Future returned by [Future.catchError]. */ 390 /** Future returned by [Future.catchError]. */
398 class _CatchErrorFuture<T> extends _TransformFuture<T,T> { 391 class _CatchErrorFuture<T> extends _TransformFuture<T,T> {
399 final _FutureErrorTest _test; 392 final _FutureErrorTest _test;
400 final _FutureOnError _onError; 393 final _FutureOnError _onError;
401 394
402 _CatchErrorFuture(this._onError, this._test); 395 _CatchErrorFuture(this._onError, this._test);
403 396
404 _sendValue(T value) { 397 _sendValue(T value) {
405 _setValue(value); 398 _setValue(value);
406 } 399 }
407 400
408 _sendError(AsyncError error) { 401 _sendError(error) {
409 assert(_onError != null); 402 assert(_onError != null);
410 // if _test is supplied, check if it returns true, otherwise just 403 // if _test is supplied, check if it returns true, otherwise just
411 // forward the error unmodified. 404 // forward the error unmodified.
412 if (_test != null) { 405 if (_test != null) {
413 bool matchesTest; 406 bool matchesTest;
414 try { 407 try {
415 matchesTest = _test(error.error); 408 matchesTest = _test(error);
416 } catch (e, s) { 409 } catch (e, s) {
417 _setError(new AsyncError.withCause(e, s, error)); 410 _setError(_asyncError(e, s));
418 return; 411 return;
419 } 412 }
420 if (!matchesTest) { 413 if (!matchesTest) {
421 _setError(error); 414 _setError(error);
422 return; 415 return;
423 } 416 }
424 } 417 }
425 // Act on the error, and use the result as this future's result. 418 // Act on the error, and use the result as this future's result.
426 var result; 419 var result;
427 try { 420 try {
428 result = _onError(error); 421 result = _onError(error);
429 } on AsyncError catch (e) {
430 _setError(e);
431 return;
432 } catch (e, s) { 422 } catch (e, s) {
433 _setError(new AsyncError.withCause(e, s, error)); 423 _setError(_asyncError(e, s));
434 return; 424 return;
435 } 425 }
436 _setOrChainValue(result); 426 _setOrChainValue(result);
437 } 427 }
438 } 428 }
439 429
440 /** Future returned by [Future.then] with an [:onError:] parameter. */ 430 /** Future returned by [Future.then] with an [:onError:] parameter. */
441 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> { 431 class _SubscribeFuture<S, T> extends _ThenFuture<S, T> {
442 final _FutureOnError _onError; 432 final _FutureOnError _onError;
443 433
444 _SubscribeFuture(onValue(S value), this._onError) : super(onValue); 434 _SubscribeFuture(onValue(S value), this._onError) : super(onValue);
445 435
446 // The _sendValue method is inherited from ThenFuture. 436 // The _sendValue method is inherited from ThenFuture.
447 437
448 void _sendError(AsyncError error) { 438 void _sendError(error) {
449 assert(_onError != null); 439 assert(_onError != null);
450 var result; 440 var result;
451 try { 441 try {
452 result = _onError(error); 442 result = _onError(error);
453 } on AsyncError catch (e) {
454 _setError(e);
455 return;
456 } catch (e, s) { 443 } catch (e, s) {
457 _setError(new AsyncError.withCause(e, s, error)); 444 _setError(_asyncError(e, s));
458 return; 445 return;
459 } 446 }
460 _setOrChainValue(result); 447 _setOrChainValue(result);
461 } 448 }
462 } 449 }
463 450
464 /** Future returned by [Future.whenComplete]. */ 451 /** Future returned by [Future.whenComplete]. */
465 class _WhenFuture<T> extends _TransformFuture<T, T> { 452 class _WhenFuture<T> extends _TransformFuture<T, T> {
466 final _FutureAction _action; 453 final _FutureAction _action;
467 454
468 _WhenFuture(this._action); 455 _WhenFuture(this._action);
469 456
470 void _sendValue(T value) { 457 void _sendValue(T value) {
471 try { 458 try {
472 var result = _action(); 459 var result = _action();
473 if (result is Future) { 460 if (result is Future) {
474 Future resultFuture = result; 461 Future resultFuture = result;
475 resultFuture.then((_) { 462 resultFuture.then((_) {
476 _setValue(value); 463 _setValue(value);
477 }, onError: _setError); 464 }, onError: _setError);
478 return; 465 return;
479 } 466 }
480 } on AsyncError catch (e) {
481 _setError(e);
482 return;
483 } catch (e, s) { 467 } catch (e, s) {
484 _setError(new AsyncError(e, s)); 468 _setError(_asyncError(e, s));
485 return; 469 return;
486 } 470 }
487 _setValue(value); 471 _setValue(value);
488 } 472 }
489 473
490 void _sendError(AsyncError error) { 474 void _sendError(error) {
491 try { 475 try {
492 var result = _action(); 476 var result = _action();
493 if (result is Future) { 477 if (result is Future) {
494 Future resultFuture = result; 478 Future resultFuture = result;
495 // TODO(lrn): Find a way to combine [error] into [e]. 479 // TODO(lrn): Find a way to combine [error] into [e].
496 resultFuture.then((_) { 480 resultFuture.then((_) {
497 _setError(error); 481 _setError(error);
498 }, onError: _setError); 482 }, onError: _setError);
499 return; 483 return;
500 } 484 }
501 } on AsyncError catch (e) {
502 error = e;
503 } catch (e, s) { 485 } catch (e, s) {
504 error = new AsyncError.withCause(e, s, error); 486 error = _asyncError(e, s);
505 } 487 }
506 _setError(error); 488 _setError(error);
507 } 489 }
508 } 490 }
509 491
510 /** 492 /**
511 * Thin wrapper around a [Future]. 493 * Thin wrapper around a [Future].
512 * 494 *
513 * This is used to return a "new" [Future] that effectively work just 495 * This is used to return a "new" [Future] that effectively work just
514 * as an existing [Future], without making this discoverable by comparing 496 * as an existing [Future], without making this discoverable by comparing
515 * identities. 497 * identities.
516 */ 498 */
517 class _FutureWrapper<T> implements Future<T> { 499 class _FutureWrapper<T> implements Future<T> {
518 final Future<T> _future; 500 final Future<T> _future;
519 501
520 _FutureWrapper(this._future); 502 _FutureWrapper(this._future);
521 503
522 Future then(function(T value), { onError(AsyncError error) }) { 504 Future then(function(T value), { onError(error) }) {
523 return _future.then(function, onError: onError); 505 return _future.then(function, onError: onError);
524 } 506 }
525 507
526 Future catchError(function(AsyncError error), {bool test(var error)}) { 508 Future catchError(function(error), {bool test(var error)}) {
527 return _future.catchError(function, test: test); 509 return _future.catchError(function, test: test);
528 } 510 }
529 511
530 Future<T> whenComplete(action()) { 512 Future<T> whenComplete(action()) {
531 return _future.whenComplete(action); 513 return _future.whenComplete(action);
532 } 514 }
533 515
534 Stream<T> asStream() => new Stream.fromFuture(_future); 516 Stream<T> asStream() => new Stream.fromFuture(_future);
535 } 517 }
OLDNEW
« no previous file with comments | « sdk/lib/async/future.dart ('k') | sdk/lib/async/stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698