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

Side by Side Diff: test/generated_sdk/lib/async/future.dart

Issue 1162723007: remove generated_sdk from checked in code (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 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
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of dart.async;
6
7 /**
8 * An object representing a delayed computation.
9 *
10 * A [Future] is used to represent a potential value, or error,
11 * that will be available at some time in the future.
12 * Receivers of a [Future] can register callbacks
13 * that handle the value or error once it is available.
14 * For example:
15 *
16 * Future<int> future = getFuture();
17 * future.then((value) => handleValue(value))
18 * .catchError((error) => handleError(error));
19 *
20 * A [Future] can complete in two ways:
21 * with a value ("the future succeeds")
22 * or with an error ("the future fails").
23 * Users can install callbacks for each case.
24 * The result of registering a pair of callbacks is a new Future (the
25 * "successor") which in turn is completed with the result of invoking the
26 * corresponding callback.
27 * The successor is completed with an error if the invoked callback throws.
28 * For example:
29 *
30 * Future<int> successor = future.then((int value) {
31 * // Invoked when the future is completed with a value.
32 * return 42; // The successor is completed with the value 42.
33 * },
34 * onError: (e) {
35 * // Invoked when the future is completed with an error.
36 * if (canHandle(e)) {
37 * return 499; // The successor is completed with the value 499.
38 * } else {
39 * throw e; // The successor is completed with the error e.
40 * }
41 * });
42 *
43 * If a future does not have a successor when it completes with an error,
44 * it forwards the error message to the global error-handler.
45 * This behavior makes sure that no error is silently dropped.
46 * However, it also means that error handlers should be installed early,
47 * so that they are present as soon as a future is completed with an error.
48 * The following example demonstrates this potential bug:
49 *
50 * var future = getFuture();
51 * new Timer(new Duration(milliseconds: 5), () {
52 * // The error-handler is not attached until 5 ms after the future has
53 * // been received. If the future fails before that, the error is
54 * // forwarded to the global error-handler, even though there is code
55 * // (just below) to eventually handle the error.
56 * future.then((value) { useValue(value); },
57 * onError: (e) { handleError(e); });
58 * });
59 *
60 * When registering callbacks, it's often more readable to register the two
61 * callbacks separately, by first using [then] with one argument
62 * (the value handler) and using a second [catchError] for handling errors.
63 * Each of these will forward the result that they don't handle
64 * to their successors, and together they handle both value and error result.
65 * It also has the additional benefit of the [catchError] handling errors in the
66 * [then] value callback too.
67 * Using sequential handlers instead of parallel ones often leads to code that
68 * is easier to reason about.
69 * It also makes asynchronous code very similar to synchronous code:
70 *
71 * // Synchronous code.
72 * try {
73 * int value = foo();
74 * return bar(value);
75 * } catch (e) {
76 * return 499;
77 * }
78 *
79 * Equivalent asynchronous code, based on futures:
80 *
81 * Future<int> future = new Future(foo); // Result of foo() as a future.
82 * future.then((int value) => bar(value))
83 * .catchError((e) => 499);
84 *
85 * Similar to the synchronous code, the error handler (registered with
86 * [catchError]) is handling any errors thrown by either `foo` or `bar`.
87 * If the error-handler had been registered as the `onError` parameter of
88 * the `then` call, it would not catch errors from the `bar` call.
89 *
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.
92 *
93 * A future may also fail to ever complete. In that case, no callbacks are
94 * called.
95 */
96 abstract class Future<T> {
97 // The `_nullFuture` is a completed Future with the value `null`.
98 static final _Future _nullFuture = new _Future.immediate(null);
99
100 /**
101 * Creates a future containing the result of calling [computation]
102 * asynchronously with [Timer.run].
103 *
104 * If the result of executing [computation] throws, the returned future is
105 * completed with the error.
106 *
107 * If the returned value is itself a [Future], completion of
108 * the created future will wait until the returned future completes,
109 * and will then complete with the same result.
110 *
111 * If a non-future value is returned, the returned future is completed
112 * with that value.
113 */
114 factory Future(computation()) {
115 _Future result = new _Future<T>();
116 Timer.run(() {
117 try {
118 result._complete(computation());
119 } catch (e, s) {
120 _completeWithErrorCallback(result, e, s);
121 }
122 });
123 return result;
124 }
125
126 /**
127 * Creates a future containing the result of calling [computation]
128 * asynchronously with [scheduleMicrotask].
129 *
130 * If executing [computation] throws,
131 * the returned future is completed with the thrown error.
132 *
133 * If calling [computation] returns a [Future], completion of
134 * the created future will wait until the returned future completes,
135 * and will then complete with the same result.
136 *
137 * If calling [computation] returns a non-future value,
138 * the returned future is completed with that value.
139 */
140 factory Future.microtask(computation()) {
141 _Future result = new _Future<T>();
142 scheduleMicrotask(() {
143 try {
144 result._complete(computation());
145 } catch (e, s) {
146 _completeWithErrorCallback(result, e, s);
147 }
148 });
149 return result;
150 }
151
152 /**
153 * Creates a future containing the result of immediately calling
154 * [computation].
155 *
156 * If calling [computation] throws, the returned future is completed with the
157 * error.
158 *
159 * If calling [computation] returns a [Future], completion of
160 * the created future will wait until the returned future completes,
161 * and will then complete with the same result.
162 *
163 * If calling [computation] returns a non-future value,
164 * the returned future is completed with that value.
165 */
166 factory Future.sync(computation()) {
167 try {
168 var result = computation();
169 return new Future<T>.value(result);
170 } catch (error, stackTrace) {
171 return new Future<T>.error(error, stackTrace);
172 }
173 }
174
175 /**
176 * A future whose value is available in the next event-loop iteration.
177 *
178 * If [value] is not a [Future], using this constructor is equivalent
179 * to [:new Future<T>.sync(() => value):].
180 *
181 * Use [Completer] to create a Future and complete it later.
182 */
183 factory Future.value([value]) {
184 return new _Future<T>.immediate(value);
185 }
186
187 /**
188 * A future that completes with an error in the next event-loop iteration.
189 *
190 * If [error] is `null`, it is replaced by a [NullThrownError].
191 *
192 * Use [Completer] to create a future and complete it later.
193 */
194 factory Future.error(Object error, [StackTrace stackTrace]) {
195 error = _nonNullError(error);
196 if (!identical(Zone.current, _ROOT_ZONE)) {
197 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
198 if (replacement != null) {
199 error = _nonNullError(replacement.error);
200 stackTrace = replacement.stackTrace;
201 }
202 }
203 return new _Future<T>.immediateError(error, stackTrace);
204 }
205
206 /**
207 * Creates a future that runs its computation after a delay.
208 *
209 * The [computation] will be executed after the given [duration] has passed,
210 * and the future is completed with the result.
211 * If the duration is 0 or less,
212 * it completes no sooner than in the next event-loop iteration.
213 *
214 * If [computation] is omitted,
215 * it will be treated as if [computation] was set to `() => null`,
216 * and the future will eventually complete with the `null` value.
217 *
218 * If calling [computation] throws, the created future will complete with the
219 * error.
220 *
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.
223 */
224 factory Future.delayed(Duration duration, [T computation()]) {
225 _Future result = new _Future<T>();
226 new Timer(duration, () {
227 try {
228 result._complete(computation == null ? null : computation());
229 } catch (e, s) {
230 _completeWithErrorCallback(result, e, s);
231 }
232 });
233 return result;
234 }
235
236 /**
237 * Wait for all the given futures to complete and collect their values.
238 *
239 * Returns a future which will complete once all the futures in a list are
240 * complete. If any of the futures in the list completes with an error,
241 * the resulting future also completes with an error. Otherwise the value
242 * of the returned future will be a list of all the values that were
243 * produced.
244 *
245 * If `eagerError` is true, the future completes with an error immediately on
246 * the first error from one of the futures. Otherwise all futures must
247 * complete before the returned future is completed (still with the first
248 * error to occur, the remaining errors are silently dropped).
249 *
250 * If [cleanUp] is provided, in the case of an error, any non-null result of
251 * a successful future is passed to `cleanUp`, which can then release any
252 * resources that the successful operation allocated.
253 *
254 * The call to `cleanUp` should not throw. If it does, the error will be an
255 * uncaught asynchronous error.
256 */
257 static Future<List> wait(Iterable<Future> futures,
258 {bool eagerError: false,
259 void cleanUp(successValue)}) {
260 final _Future<List> result = new _Future<List>();
261 List values; // Collects the values. Set to null on error.
262 int remaining = 0; // How many futures are we waiting for.
263 var error; // The first error from a future.
264 StackTrace stackTrace; // The stackTrace that came with the error.
265
266 // Handle an error from any of the futures.
267 void handleError(theError, theStackTrace) {
268 remaining--;
269 if (values != null) {
270 if (cleanUp != null) {
271 for (var value in values) {
272 if (value != null) {
273 // Ensure errors from cleanUp are uncaught.
274 new Future.sync(() { cleanUp(value); });
275 }
276 }
277 }
278 values = null;
279 if (remaining == 0 || eagerError) {
280 result._completeError(theError, theStackTrace);
281 } else {
282 error = theError;
283 stackTrace = theStackTrace;
284 }
285 } else if (remaining == 0 && !eagerError) {
286 result._completeError(error, stackTrace);
287 }
288 }
289
290 // As each future completes, put its value into the corresponding
291 // position in the list of values.
292 for (Future future in futures) {
293 int pos = remaining++;
294 future.then((Object value) {
295 remaining--;
296 if (values != null) {
297 values[pos] = value;
298 if (remaining == 0) {
299 result._completeWithValue(values);
300 }
301 } else {
302 if (cleanUp != null && value != null) {
303 // Ensure errors from cleanUp are uncaught.
304 new Future.sync(() { cleanUp(value); });
305 }
306 if (remaining == 0 && !eagerError) {
307 result._completeError(error, stackTrace);
308 }
309 }
310 }, onError: handleError);
311 }
312 if (remaining == 0) {
313 return new Future.value(const []);
314 }
315 values = new List(remaining);
316 return result;
317 }
318
319 /**
320 * Perform an async operation for each element of the iterable, in turn.
321 *
322 * 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
324 * completes when all elements have been processed.
325 *
326 * 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].
328 *
329 * If [f] returns a non-[Future], iteration continues immediately. Otherwise
330 * it waits for the returned [Future] to complete.
331 */
332 static Future forEach(Iterable input, f(element)) {
333 Iterator iterator = input.iterator;
334 return doWhile(() {
335 if (!iterator.moveNext()) return false;
336 return new Future.sync(() => f(iterator.current)).then((_) => true);
337 });
338 }
339
340 /**
341 * Perform an async operation repeatedly until it returns `false`.
342 *
343 * Runs [f] repeatedly, starting the next iteration only when the [Future]
344 * returned by [f] completes to `true`. Returns a [Future] that completes once
345 * [f] returns `false`.
346 *
347 * The return values of all [Future]s are discarded. Any errors will cause the
348 * iteration to stop and will be piped through the returned [Future].
349 *
350 * The function [f] may return either a [bool] or a [Future] that completes to
351 * a [bool]. If it returns a non-[Future], iteration continues immediately.
352 * Otherwise it waits for the returned [Future] to complete.
353 */
354 static Future doWhile(f()) {
355 _Future doneSignal = new _Future();
356 var nextIteration;
357 // Bind this callback explicitly so that each iteration isn't bound in the
358 // context of all the previous iterations' callbacks.
359 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) {
360 if (keepGoing) {
361 new Future.sync(f).then(nextIteration,
362 onError: doneSignal._completeError);
363 } else {
364 doneSignal._complete(null);
365 }
366 }, runGuarded: true);
367 nextIteration(true);
368 return doneSignal;
369 }
370
371 /**
372 * Register callbacks to be called when this future completes.
373 *
374 * When this future completes with a value,
375 * the [onValue] callback will be called with that value.
376 * If this future is already completed, the callback will not be called
377 * immediately, but will be scheduled in a later microtask.
378 *
379 * If [onError] is provided, and this future completes with an error,
380 * the `onError` callback is called with that error and its stack trace.
381 * The `onError` callback must accept either one argument or two arguments.
382 * If `onError` accepts two arguments,
383 * it is called with both the error and the stack trace,
384 * otherwise it is called with just the error object.
385 *
386 * Returns a new [Future]
387 * which is completed with the result of the call to `onValue`
388 * (if this future completes with a value)
389 * or to `onError` (if this future completes with an error).
390 *
391 * If the invoked callback throws,
392 * the returned future is completed with the thrown error
393 * and a stack trace for the error.
394 * In the case of `onError`,
395 * if the exception thrown is `identical` to the error argument to `onError`,
396 * the throw is considered a rethrow,
397 * and the original stack trace is used instead.
398 *
399 * If the callback returns a [Future],
400 * the future returned by `then` will be completed with
401 * the same result as the future returned by the callback.
402 *
403 * If [onError] is not given, and this future completes with an error,
404 * the error is forwarded directly to the returned future.
405 *
406 * In most cases, it is more readable to use [catchError] separately, possibly
407 * with a `test` parameter, instead of handling both value and error in a
408 * single [then] call.
409 */
410 Future then(onValue(T value), { Function onError });
411
412 /**
413 * Handles errors emitted by this [Future].
414 *
415 * This is the asynchronous equivalent of a "catch" block.
416 *
417 * Returns a new [Future] that will be completed with either the result of
418 * this future or the result of calling the `onError` callback.
419 *
420 * If this future completes with a value,
421 * the returned future completes with the same value.
422 *
423 * If this future completes with an error,
424 * then [test] is first called with the error value.
425 *
426 * If `test` returns false, the exception is not handled by this `catchError`,
427 * and the returned future completes with the same error and stack trace
428 * as this future.
429 *
430 * If `test` returns `true`,
431 * [onError] is called with the error and possibly stack trace,
432 * and the returned future is completed with the result of this call
433 * in exactly the same way as for [then]'s `onError`.
434 *
435 * If `test` is omitted, it defaults to a function that always returns true.
436 * The `test` function should not throw, but if it does, it is handled as
437 * if the the `onError` function had thrown.
438 *
439 * Example:
440 *
441 * foo
442 * .catchError(..., test: (e) => e is ArgumentError)
443 * .catchError(..., test: (e) => e is NoSuchMethodError)
444 * .then((v) { ... });
445 *
446 * This method is equivalent to:
447 *
448 * Future catchError(onError(error),
449 * {bool test(error)}) {
450 * this.then((v) => v, // Forward the value.
451 * // But handle errors, if the [test] succeeds.
452 * onError: (e, stackTrace) {
453 * if (test == null || test(e)) {
454 * if (onError is ZoneBinaryCallback) {
455 * return onError(e, stackTrace);
456 * }
457 * return onError(e);
458 * }
459 * throw e;
460 * });
461 * }
462 *
463 */
464 Future catchError(Function onError,
465 {bool test(Object error)});
466
467 /**
468 * Register a function to be called when this future completes.
469 *
470 * The [action] function is called when this future completes, whether it
471 * does so with a value or with an error.
472 *
473 * This is the asynchronous equivalent of a "finally" block.
474 *
475 * The future returned by this call, `f`, will complete the same way
476 * as this future unless an error occurs in the [action] call, or in
477 * a [Future] returned by the [action] call. If the call to [action]
478 * does not return a future, its return value is ignored.
479 *
480 * If the call to [action] throws, then `f` is completed with the
481 * thrown error.
482 *
483 * If the call to [action] returns a [Future], `f2`, then completion of
484 * `f` is delayed until `f2` completes. If `f2` completes with
485 * an error, that will be the result of `f` too. The value of `f2` is always
486 * ignored.
487 *
488 * This method is equivalent to:
489 *
490 * Future<T> whenComplete(action()) {
491 * return this.then((v) {
492 * var f2 = action();
493 * if (f2 is Future) return f2.then((_) => v);
494 * return v
495 * }, onError: (e) {
496 * var f2 = action();
497 * if (f2 is Future) return f2.then((_) { throw e; });
498 * throw e;
499 * });
500 * }
501 */
502 Future<T> whenComplete(action());
503
504 /**
505 * Creates a [Stream] containing the result of this future.
506 *
507 * The stream will produce single data or error event containing the
508 * completion result of this future, and then it will close with a
509 * done event.
510 *
511 * If the future never completes, the stream will not produce any events.
512 */
513 Stream<T> asStream();
514
515 /**
516 * Time-out the future computation after [timeLimit] has passed.
517 *
518 * Returns a new future that completes with the same value as this future,
519 * if this future completes in time.
520 *
521 * If this future does not complete before `timeLimit` has passed,
522 * the [onTimeout] action is executed instead, and its result (whether it
523 * returns or throws) is used as the result of the returned future.
524 *
525 * If `onTimeout` is omitted, a timeout will cause the returned future to
526 * complete with a [TimeoutException].
527 */
528 Future timeout(Duration timeLimit, {onTimeout()});
529 }
530
531 /**
532 * Thrown when a scheduled timeout happens while waiting for an async result.
533 */
534 class TimeoutException implements Exception {
535 /** Description of the cause of the timeout. */
536 final String message;
537 /** The duration that was exceeded. */
538 final Duration duration;
539
540 TimeoutException(this.message, [this.duration]);
541
542 String toString() {
543 String result = "TimeoutException";
544 if (duration != null) result = "TimeoutException after $duration";
545 if (message != null) result = "$result: $message";
546 return result;
547 }
548 }
549
550 /**
551 * A way to produce Future objects and to complete them later
552 * with a value or error.
553 *
554 * Most of the time, the simplest way to create a future is to just use
555 * one of the [Future] constructors to capture the result of a single
556 * asynchronous computation:
557 *
558 * new Future(() { doSomething(); return result; });
559 *
560 * or, if the future represents the result of a sequence of asynchronous
561 * computations, they can be chained using [Future.then] or similar functions
562 * on [Future]:
563 *
564 * Future doStuff(){
565 * return someAsyncOperation().then((result) {
566 * return someOtherAsyncOperation(result);
567 * });
568 * }
569 *
570 * If you do need to create a Future from scratch — for example,
571 * when you're converting a callback-based API into a Future-based
572 * one — you can use a Completer as follows:
573 *
574 * class AsyncOperation {
575 * Completer _completer = new Completer();
576 *
577 * Future<T> doOperation() {
578 * _startOperation();
579 * return _completer.future; // Send future object back to client.
580 * }
581 *
582 * // Something calls this when the value is ready.
583 * void _finishOperation(T result) {
584 * _completer.complete(result);
585 * }
586 *
587 * // If something goes wrong, call this.
588 * void _errorHappened(error) {
589 * _completer.completeError(error);
590 * }
591 * }
592 */
593 abstract class Completer<T> {
594
595 /**
596 * Creates a new completer.
597 *
598 * The general workflow for creating a new future is to 1) create a
599 * new completer, 2) hand out its future, and, at a later point, 3) invoke
600 * either [complete] or [completeError].
601 *
602 * The completer completes the future asynchronously. That means that
603 * callbacks registered on the future, are not called immediately when
604 * [complete] or [completeError] is called. Instead the callbacks are
605 * delayed until a later microtask.
606 *
607 * Example:
608 *
609 * var completer = new Completer();
610 * handOut(completer.future);
611 * later: {
612 * completer.complete('completion value');
613 * }
614 */
615 factory Completer() => new _AsyncCompleter<T>();
616
617 /**
618 * Completes the future synchronously.
619 *
620 * 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
622 * use the default [Completer] constructor.
623 *
624 * Using an normal, asynchronous, completer will never give the wrong
625 * behavior, but using a synchronous completer incorrectly can cause
626 * otherwise correct programs to break.
627 *
628 * An asynchronous completer is only intended for optimizing event
629 * propagation when one asynchronous event immediately triggers another.
630 * 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.
632 *
633 * Completing synchronously means that the completer's future will be
634 * completed immediately when calling the [complete] or [completeError]
635 * method on a synchronous completer, which also calls any callbacks
636 * registered on that future.
637 *
638 * Completing synchronously must not break the rule that when you add a
639 * callback on a future, that callback must not be called until the code
640 * that added the callback has completed.
641 * For that reason, a synchronous completion must only occur at the very end
642 * (in "tail position") of another synchronous event,
643 * because at that point, completing the future immediately is be equivalent
644 * to returning to the event loop and completing the future in the next
645 * microtask.
646 *
647 * Example:
648 *
649 * var completer = new Completer.sync();
650 * // The completion is the result of the asynchronous onDone event.
651 * // No other operation is performed after the completion. It is safe
652 * // to use the Completer.sync constructor.
653 * stream.listen(print, onDone: () { completer.complete("done"); });
654 *
655 * Bad example. Do not use this code. Only for illustrative purposes:
656 *
657 * var completer = new Completer.sync();
658 * completer.future.then((_) { bar(); });
659 * // The completion is the result of the asynchronous onDone event.
660 * // However, there is still code executed after the completion. This
661 * // operation is *not* safe.
662 * stream.listen(print, onDone: () {
663 * completer.complete("done");
664 * foo(); // In this case, foo() runs after bar().
665 * });
666 */
667 factory Completer.sync() => new _SyncCompleter<T>();
668
669 /** The future that will contain the result provided to this completer. */
670 Future<T> get future;
671
672 /**
673 * Completes [future] with the supplied values.
674 *
675 * The value must be either a value of type [T]
676 * or a future of type `Future<T>`.
677 *
678 * If the value is itself a future, the completer will wait for that future
679 * to complete, and complete with the same result, whether it is a success
680 * or an error.
681 *
682 * Calling `complete` or [completeError] must not be done more than once.
683 *
684 * All listeners on the future are informed about the value.
685 */
686 void complete([value]);
687
688 /**
689 * Complete [future] with an error.
690 *
691 * Calling [complete] or `completeError` must not be done more than once.
692 *
693 * Completing a future with an error indicates that an exception was thrown
694 * while trying to produce a value.
695 *
696 * If [error] is `null`, it is replaced by a [NullThrownError].
697 *
698 * If `error` is a `Future`, the future itself is used as the error value.
699 * If you want to complete with the result of the future, you can use:
700 *
701 * thisCompleter.complete(theFuture)
702 *
703 * or if you only want to handle an error from the future:
704 *
705 * theFuture.catchError(thisCompleter.completeError);
706 *
707 */
708 void completeError(Object error, [StackTrace stackTrace]);
709
710 /**
711 * Whether the future has been completed.
712 */
713 bool get isCompleted;
714 }
715
716 // Helper function completing a _Future with error, but checking the zone
717 // for error replacement first.
718 void _completeWithErrorCallback(_Future result, error, stackTrace) {
719 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
720 if (replacement != null) {
721 error = _nonNullError(replacement.error);
722 stackTrace = replacement.stackTrace;
723 }
724 result._completeError(error, stackTrace);
725 }
726
727 /** Helper function that converts `null` to a [NullThrownError]. */
728 Object _nonNullError(Object error) =>
729 (error != null) ? error : new NullThrownError();
OLDNEW
« no previous file with comments | « test/generated_sdk/lib/async/deferred_load.dart ('k') | test/generated_sdk/lib/async/future_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698