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

Side by Side Diff: tool/input_sdk/lib/async/future.dart

Issue 1953153002: Update dart:async to match the Dart repo. (Closed) Base URL: https://github.com/dart-lang/dev_compiler.git@master
Patch Set: Remove unneeded calls. Created 4 years, 7 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
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 /** 7 /**
8 * An object representing a delayed computation. 8 * An object representing a delayed computation.
9 * 9 *
10 * A [Future] is used to represent a potential value, or error, 10 * A [Future] is used to represent a potential value, or error,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 * the `then` call, it would not catch errors from the `bar` call. 88 * the `then` call, it would not catch errors from the `bar` call.
89 * 89 *
90 * Futures can have more than one callback-pair registered. Each successor is 90 * Futures can have more than one callback-pair registered. Each successor is
91 * treated independently and is handled as if it was the only successor. 91 * treated independently and is handled as if it was the only successor.
92 * 92 *
93 * A future may also fail to ever complete. In that case, no callbacks are 93 * A future may also fail to ever complete. In that case, no callbacks are
94 * called. 94 * called.
95 */ 95 */
96 abstract class Future<T> { 96 abstract class Future<T> {
97 // The `_nullFuture` is a completed Future with the value `null`. 97 // The `_nullFuture` is a completed Future with the value `null`.
98 static final _Future _nullFuture = new _Future.immediate(null); 98 static final _Future _nullFuture = new Future.value(null);
99 99
100 /** 100 /**
101 * Creates a future containing the result of calling [computation] 101 * Creates a future containing the result of calling [computation]
102 * asynchronously with [Timer.run]. 102 * asynchronously with [Timer.run].
103 * 103 *
104 * If the result of executing [computation] throws, the returned future is 104 * If the result of executing [computation] throws, the returned future is
105 * completed with the error. 105 * completed with the error.
106 * 106 *
107 * If the returned value is itself a [Future], completion of 107 * If the returned value is itself a [Future], completion of
108 * the created future will wait until the returned future completes, 108 * the created future will wait until the returned future completes,
109 * and will then complete with the same result. 109 * and will then complete with the same result.
110 * 110 *
111 * If a non-future value is returned, the returned future is completed 111 * If a non-future value is returned, the returned future is completed
112 * with that value. 112 * with that value.
113 */ 113 */
114 factory Future(computation()) { 114 factory Future(computation()) {
115 _Future result = new _Future<T>(); 115 _Future<T> result = new _Future<T>();
116 Timer.run(() { 116 Timer.run(() {
117 try { 117 try {
118 result._complete(computation()); 118 result._complete(computation());
119 } catch (e, s) { 119 } catch (e, s) {
120 _completeWithErrorCallback(result, e, s); 120 _completeWithErrorCallback(result, e, s);
121 } 121 }
122 }); 122 });
123 return result; 123 return result;
124 } 124 }
125 125
126 /** 126 /**
127 * Creates a future containing the result of calling [computation] 127 * Creates a future containing the result of calling [computation]
128 * asynchronously with [scheduleMicrotask]. 128 * asynchronously with [scheduleMicrotask].
129 * 129 *
130 * If executing [computation] throws, 130 * If executing [computation] throws,
131 * the returned future is completed with the thrown error. 131 * the returned future is completed with the thrown error.
132 * 132 *
133 * If calling [computation] returns a [Future], completion of 133 * If calling [computation] returns a [Future], completion of
134 * the created future will wait until the returned future completes, 134 * the created future will wait until the returned future completes,
135 * and will then complete with the same result. 135 * and will then complete with the same result.
136 * 136 *
137 * If calling [computation] returns a non-future value, 137 * If calling [computation] returns a non-future value,
138 * the returned future is completed with that value. 138 * the returned future is completed with that value.
139 */ 139 */
140 factory Future.microtask(computation()) { 140 factory Future.microtask(computation()) {
141 _Future result = new _Future<T>(); 141 _Future<T> result = new _Future<T>();
142 scheduleMicrotask(() { 142 scheduleMicrotask(() {
143 try { 143 try {
144 result._complete(computation()); 144 result._complete(computation());
145 } catch (e, s) { 145 } catch (e, s) {
146 _completeWithErrorCallback(result, e, s); 146 _completeWithErrorCallback(result, e, s);
147 } 147 }
148 }); 148 });
149 return result; 149 return result;
150 } 150 }
151 151
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 * If [computation] is omitted, 214 * If [computation] is omitted,
215 * it will be treated as if [computation] was set to `() => null`, 215 * it will be treated as if [computation] was set to `() => null`,
216 * and the future will eventually complete with the `null` value. 216 * and the future will eventually complete with the `null` value.
217 * 217 *
218 * If calling [computation] throws, the created future will complete with the 218 * If calling [computation] throws, the created future will complete with the
219 * error. 219 * error.
220 * 220 *
221 * See also [Completer] for a way to create and complete a future at a 221 * See also [Completer] for a way to create and complete a future at a
222 * later time that isn't necessarily after a known fixed duration. 222 * later time that isn't necessarily after a known fixed duration.
223 */ 223 */
224 factory Future.delayed(Duration duration, [T computation()]) { 224 factory Future.delayed(Duration duration, [computation()]) {
225 _Future result = new _Future<T>(); 225 _Future<T> result = new _Future<T>();
226 new Timer(duration, () { 226 new Timer(duration, () {
227 try { 227 try {
228 result._complete(computation == null ? null : computation()); 228 result._complete(computation == null ? null : computation());
229 } catch (e, s) { 229 } catch (e, s) {
230 _completeWithErrorCallback(result, e, s); 230 _completeWithErrorCallback(result, e, s);
231 } 231 }
232 }); 232 });
233 return result; 233 return result;
234 } 234 }
235 235
(...skipping 25 matching lines...) Expand all
261 List/*<T>*/ values; // Collects the values. Set to null on error. 261 List/*<T>*/ values; // Collects the values. Set to null on error.
262 int remaining = 0; // How many futures are we waiting for. 262 int remaining = 0; // How many futures are we waiting for.
263 var error; // The first error from a future. 263 var error; // The first error from a future.
264 StackTrace stackTrace; // The stackTrace that came with the error. 264 StackTrace stackTrace; // The stackTrace that came with the error.
265 265
266 // Handle an error from any of the futures. 266 // Handle an error from any of the futures.
267 void handleError(theError, theStackTrace) { 267 void handleError(theError, theStackTrace) {
268 remaining--; 268 remaining--;
269 if (values != null) { 269 if (values != null) {
270 if (cleanUp != null) { 270 if (cleanUp != null) {
271 for (var value2 in values) { 271 for (var value in values) {
272 if (value2 != null) { 272 if (value != null) {
273 // Ensure errors from cleanUp are uncaught. 273 // Ensure errors from cleanUp are uncaught.
274 new Future.sync(() { cleanUp(value2); }); 274 new Future.sync(() { cleanUp(value); });
275 } 275 }
276 } 276 }
277 } 277 }
278 values = null; 278 values = null;
279 if (remaining == 0 || eagerError) { 279 if (remaining == 0 || eagerError) {
280 result._completeError(theError, theStackTrace); 280 result._completeError(theError, theStackTrace);
281 } else { 281 } else {
282 error = theError; 282 error = theError;
283 stackTrace = theStackTrace; 283 stackTrace = theStackTrace;
284 } 284 }
285 } else if (remaining == 0 && !eagerError) { 285 } else if (remaining == 0 && !eagerError) {
286 result._completeError(error, stackTrace); 286 result._completeError(error, stackTrace);
287 } 287 }
288 } 288 }
289 289
290 // As each future completes, put its value into the corresponding 290 // As each future completes, put its value into the corresponding
291 // position in the list of values. 291 // position in the list of values.
292 for (Future future in futures) { 292 for (Future future in futures) {
293 int pos = remaining++; 293 int pos = remaining++;
294 future.then((Object value) { 294 future.then((Object/*=T*/ value) {
295 remaining--; 295 remaining--;
296 if (values != null) { 296 if (values != null) {
297 values[pos] = value; 297 values[pos] = value;
298 if (remaining == 0) { 298 if (remaining == 0) {
299 result._completeWithValue(values); 299 result._completeWithValue(values);
300 } 300 }
301 } else { 301 } else {
302 if (cleanUp != null && value != null) { 302 if (cleanUp != null && value != null) {
303 // Ensure errors from cleanUp are uncaught. 303 // Ensure errors from cleanUp are uncaught.
304 new Future.sync(() { cleanUp(value); }); 304 new Future.sync(() { cleanUp(value); });
305 } 305 }
306 if (remaining == 0 && !eagerError) { 306 if (remaining == 0 && !eagerError) {
307 result._completeError(error, stackTrace); 307 result._completeError(error, stackTrace);
308 } 308 }
309 } 309 }
310 }, onError: handleError); 310 }, onError: handleError);
311 } 311 }
312 if (remaining == 0) { 312 if (remaining == 0) {
313 return new Future.value(const []); 313 return new Future.value(const []);
314 } 314 }
315 values = new List/*<T>*/(remaining); 315 values = new List/*<T>*/(remaining);
316 return result; 316 return result;
317 } 317 }
318 318
319 /** 319 /**
320 * Returns the result of the first future in [futures] to complete.
321 *
322 * The returned future is completed with the result of the first
323 * future in [futures] to report that it is complete.
324 * The results of all the other futures are discarded.
325 *
326 * If [futures] is empty, or if none of its futures complete,
327 * the returned future never completes.
328 */
329 static Future/*<T>*/ any/*<T>*/(Iterable<Future/*<T>*/> futures) {
330 var completer = new Completer/*<T>*/.sync();
331 var onValue = (/*=T*/ value) {
332 if (!completer.isCompleted) completer.complete(value);
333 };
334 var onError = (error, stack) {
335 if (!completer.isCompleted) completer.completeError(error, stack);
336 };
337 for (var future in futures) {
338 future.then(onValue, onError: onError);
339 }
340 return completer.future;
341 }
342
343
344 /**
320 * Perform an async operation for each element of the iterable, in turn. 345 * Perform an async operation for each element of the iterable, in turn.
321 * 346 *
322 * Runs [f] for each element in [input] in order, moving to the next element 347 * Runs [f] for each element in [input] in order, moving to the next element
323 * only when the [Future] returned by [f] completes. Returns a [Future] that 348 * only when the [Future] returned by [f] completes. Returns a [Future] that
324 * completes when all elements have been processed. 349 * completes when all elements have been processed.
325 * 350 *
326 * The return values of all [Future]s are discarded. Any errors will cause the 351 * The return values of all [Future]s are discarded. Any errors will cause the
327 * iteration to stop and will be piped through the returned [Future]. 352 * iteration to stop and will be piped through the returned [Future].
328 * 353 *
329 * If [f] returns a non-[Future], iteration continues immediately. Otherwise 354 * If [f] returns a non-[Future], iteration continues immediately. Otherwise
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 * if (onError is ZoneBinaryCallback) { 479 * if (onError is ZoneBinaryCallback) {
455 * return onError(e, stackTrace); 480 * return onError(e, stackTrace);
456 * } 481 * }
457 * return onError(e); 482 * return onError(e);
458 * } 483 * }
459 * throw e; 484 * throw e;
460 * }); 485 * });
461 * } 486 * }
462 * 487 *
463 */ 488 */
464 Future catchError(Function onError, 489 // The `Function` below can stand for several types:
465 {bool test(Object error)}); 490 // - (dynamic) -> T
491 // - (dynamic, StackTrace) -> T
492 // - (dynamic) -> Future<T>
493 // - (dynamic, StackTrace) -> Future<T>
494 // Given that there is a `test` function that is usually used to do an
495 // `isCheck` we should also expect functions that take a specific argument.
496 // Note: making `catchError` return a `Future<T>` in non-strong mode could be
497 // a breaking change.
498 Future/*<T>*/ catchError(Function onError,
499 {bool test(Object error)});
466 500
467 /** 501 /**
468 * Register a function to be called when this future completes. 502 * Register a function to be called when this future completes.
469 * 503 *
470 * The [action] function is called when this future completes, whether it 504 * The [action] function is called when this future completes, whether it
471 * does so with a value or with an error. 505 * does so with a value or with an error.
472 * 506 *
473 * This is the asynchronous equivalent of a "finally" block. 507 * This is the asynchronous equivalent of a "finally" block.
474 * 508 *
475 * The future returned by this call, `f`, will complete the same way 509 * The future returned by this call, `f`, will complete the same way
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
514 548
515 /** 549 /**
516 * Time-out the future computation after [timeLimit] has passed. 550 * Time-out the future computation after [timeLimit] has passed.
517 * 551 *
518 * Returns a new future that completes with the same value as this future, 552 * Returns a new future that completes with the same value as this future,
519 * if this future completes in time. 553 * if this future completes in time.
520 * 554 *
521 * If this future does not complete before `timeLimit` has passed, 555 * If this future does not complete before `timeLimit` has passed,
522 * the [onTimeout] action is executed instead, and its result (whether it 556 * the [onTimeout] action is executed instead, and its result (whether it
523 * returns or throws) is used as the result of the returned future. 557 * returns or throws) is used as the result of the returned future.
558 * The [onTimeout] function must return a [T] or a `Future<T>`.
524 * 559 *
525 * If `onTimeout` is omitted, a timeout will cause the returned future to 560 * If `onTimeout` is omitted, a timeout will cause the returned future to
526 * complete with a [TimeoutException]. 561 * complete with a [TimeoutException].
527 */ 562 */
528 Future timeout(Duration timeLimit, {onTimeout()}); 563 Future<T> timeout(Duration timeLimit, {onTimeout()});
529 } 564 }
530 565
531 /** 566 /**
532 * Thrown when a scheduled timeout happens while waiting for an async result. 567 * Thrown when a scheduled timeout happens while waiting for an async result.
533 */ 568 */
534 class TimeoutException implements Exception { 569 class TimeoutException implements Exception {
535 /** Description of the cause of the timeout. */ 570 /** Description of the cause of the timeout. */
536 final String message; 571 final String message;
537 /** The duration that was exceeded. */ 572 /** The duration that was exceeded. */
538 final Duration duration; 573 final Duration duration;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 * Completes the future synchronously. 653 * Completes the future synchronously.
619 * 654 *
620 * This constructor should be avoided unless the completion of the future is 655 * This constructor should be avoided unless the completion of the future is
621 * known to be the final result of another asynchronous operation. If in doubt 656 * known to be the final result of another asynchronous operation. If in doubt
622 * use the default [Completer] constructor. 657 * use the default [Completer] constructor.
623 * 658 *
624 * Using an normal, asynchronous, completer will never give the wrong 659 * Using an normal, asynchronous, completer will never give the wrong
625 * behavior, but using a synchronous completer incorrectly can cause 660 * behavior, but using a synchronous completer incorrectly can cause
626 * otherwise correct programs to break. 661 * otherwise correct programs to break.
627 * 662 *
628 * An asynchronous completer is only intended for optimizing event 663 * A synchronous completer is only intended for optimizing event
629 * propagation when one asynchronous event immediately triggers another. 664 * propagation when one asynchronous event immediately triggers another.
630 * It should not be used unless the calls to [complete] and [completeError] 665 * It should not be used unless the calls to [complete] and [completeError]
631 * are guaranteed to occur in places where it won't break `Future` invariants. 666 * are guaranteed to occur in places where it won't break `Future` invariants.
632 * 667 *
633 * Completing synchronously means that the completer's future will be 668 * Completing synchronously means that the completer's future will be
634 * completed immediately when calling the [complete] or [completeError] 669 * completed immediately when calling the [complete] or [completeError]
635 * method on a synchronous completer, which also calls any callbacks 670 * method on a synchronous completer, which also calls any callbacks
636 * registered on that future. 671 * registered on that future.
637 * 672 *
638 * Completing synchronously must not break the rule that when you add a 673 * Completing synchronously must not break the rule that when you add a
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 if (replacement != null) { 755 if (replacement != null) {
721 error = _nonNullError(replacement.error); 756 error = _nonNullError(replacement.error);
722 stackTrace = replacement.stackTrace; 757 stackTrace = replacement.stackTrace;
723 } 758 }
724 result._completeError(error, stackTrace); 759 result._completeError(error, stackTrace);
725 } 760 }
726 761
727 /** Helper function that converts `null` to a [NullThrownError]. */ 762 /** Helper function that converts `null` to a [NullThrownError]. */
728 Object _nonNullError(Object error) => 763 Object _nonNullError(Object error) =>
729 (error != null) ? error : new NullThrownError(); 764 (error != null) ? error : new NullThrownError();
OLDNEW
« no previous file with comments | « tool/input_sdk/lib/async/broadcast_stream_controller.dart ('k') | tool/input_sdk/lib/async/future_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698