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

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

Issue 11783009: Big merge from experimental to bleeding edge. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 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/async_sources.gypi ('k') | sdk/lib/async/future_impl.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 * A [Future] is used to obtain a value sometime in the future. Receivers of a
9 * [Future] can obtain the value by passing a callback to [then]. For example:
10 *
11 * Future<int> future = getFutureFromSomewhere();
12 * future.then((value) {
13 * print("I received the number $value");
14 * });
15 *
16 * A future may complete by *succeeding* (producing a value) or *failing*
17 * (producing an error, which may be handled with [catchError]).
18 *
19 * When a future completes, the following actions happen in order:
20 *
21 * 1. if the future suceeded, handlers registered with [then] are called.
22 * 2. if the future failed, handlers registered with [catchError] are
23 * tested in sequence. Each test returning true is, have its handler
24 * called.
25 * 4. if the future failed, and no handler registered with [catchError] it
26 * is accepting the error, an error is sent to the global error handler.
27 *
28 * [Future]s are usually not created directly, but with [Completer]s.
29 */
30 abstract class Future<T> {
31 /** A future whose value is immediately available. */
32 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value);
33
34 /** A future that completes with an error. */
35 factory Future.immediateError(var error, [Object stackTrace]) {
36 return new _FutureImpl<T>.immediateError(error, stackTrace);
37 }
38
39 // TODO(floitsch): I don't think the typing is right here.
40 // Otherwise new Future<int>.wait(...) would be a Future<List<int>>. Sounds
41 // wrong.
42 factory Future.wait(List<Future> futures)
43 => new _FutureImpl<List<T>>.wait(futures);
44
45 factory Future.delayed(int milliseconds, dynamic value()) {
46 var completer = new Completer<T>();
47 new Timer(milliseconds, (_) => completer.complete(null));
48 return completer.future.then((_) => value());
49 }
50
51 /**
52 * When this future completes with a value, then [onValue] is called with this
53 * value. If [this] future is already completed then the invocation of
54 * [onValue] is delayed until the next event-loop iteration.
55 *
56 * Returns a new [Future] [:f:].
57 *
58 * If [this] is completed with an error then [:f:] is completed with the same
59 * error. If [this] is completed with a value, then [:f:]'s completion value
60 * depends on the result of invoking [onValue] with [this]' completion value.
61 *
62 * If [onValue] returns a [Future] [:f2:] then [:f:] and [:f2:] are chained.
63 * That is, [:f:] is completed with the completion value of [:f2:].
64 *
65 * Otherwise [:f:] is completed with the return value of [onValue].
66 *
67 * If [onValue] throws an exception, the returned future will receive the
68 * exception.
69 *
70 * If [onError] is provided, it is called if this future completes with an
71 * error, and its return value/throw behavior is handled the same way as
72 * for [onValue].
73 *
74 * In most cases, it is more readable to use [catchError] separately, possibly
75 * with a [:test:] parameter, instead of handling both value and error in a
76 * single [then] call.
77 */
78 Future then(onValue(T value), { onError(AsyncError asyncError) });
79
80 /**
81 * If this future is complete with an error, [test] is called with the error.
82 * If [test] returns [true], [onError] is called with the error
83 * wrapped in an [AsyncError]. The result of [onError] is handled exactly as
84 * [then]'s [onValue]. If [test] returns false, the exception is not handled
85 * by [onError]. If [test] is omitted, it defaults to a function that always
86 * returns true.
87 *
88 * Example:
89 * foo
90 * .catchError(..., test: (e) => e is ArgumentError)
91 * .catchError(..., test: (e) => e is NoSuchMethodError)
92 * .then((v) { ... });
93 */
94 Future catchError(onError(AsyncError asyncError),
95 {bool test(Object error)});
96
97 /**
98 * Register a function to be called when this future completes.
99 *
100 * The [action] function is called when this future completes, whether it
101 * does so with a value or with an error.
102 *
103 * This is the asynchronous equivalent of a "finally" block.
104 *
105 * If the call to [action] does not throw, the returned future is completed
106 * with the same result as this future.
107 *
108 * If the call to [action] throws, the returned future is completed with the
109 * thrown error.
110 */
111 Future<T> whenComplete(void action());
112
113 /**
114 * Creates a [Stream] that sends [this]' completion value, data or error, to
115 * its subscribers. The stream closes after the completion value.
116 */
117 Stream<T> asStream();
118 }
119
120 /**
121 * A [Completer] is used to produce [Future]s and supply their value when it
122 * becomes available.
123 *
124 * A service that provides values to callers, and wants to return [Future]s can
125 * use a [Completer] as follows:
126 *
127 * Completer completer = new Completer();
128 * // send future object back to client...
129 * return completer.future;
130 * ...
131 *
132 * // later when value is available, call:
133 * completer.complete(value);
134 *
135 * // alternatively, if the service cannot produce the value, it
136 * // can provide an exception:
137 * completer.completeException(exception);
138 *
139 */
140 abstract class Completer<T> {
141
142 factory Completer() => new _CompleterImpl<T>();
143
144 /** The future that will contain the value produced by this completer. */
145 Future get future;
146
147 /** Supply a value for [future]. */
148 void complete(T value);
149
150 /**
151 * Indicate in [future] that an exception occured while trying to produce its
152 * value. The argument [exception] should not be [:null:]. A [stackTrace]
153 * object can be provided as well to give the user information about where
154 * the error occurred. If omitted, it will be [:null:].
155 */
156 void completeError(Object exception, [Object stackTrace]);
157 }
158
159 class Futures {
160 /**
161 * Returns a future which will complete once all the futures in a list are
162 * complete. If any of the futures in the list completes with an exception,
163 * the resulting future also completes with an exception. (The value of the
164 * returned future will be a list of all the values that were produced.)
165 */
166 static Future<List> wait(Iterable<Future> futures) {
167 return new _FutureImpl<List>.wait(futures);
168 }
169
170 /**
171 * Runs [f] for each element in [input] in order, moving to the next element
172 * only when the [Future] returned by [f] completes. Returns a [Future] that
173 * completes when all elements have been processed.
174 *
175 * The return values of all [Future]s are discarded. Any errors will cause the
176 * iteration to stop and will be piped through the returned [Future].
177 */
178 static Future forEach(Iterable input, Future f(element)) {
179 var iterator = input.iterator;
180 Future nextElement(_) {
181 if (!iterator.moveNext()) return new Future.immediate(null);
182 return f(iterator.current).then(nextElement);
183 }
184 return nextElement(null);
185 }
186 }
OLDNEW
« no previous file with comments | « sdk/lib/async/async_sources.gypi ('k') | sdk/lib/async/future_impl.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698