OLD | NEW |
---|---|
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 * A [Future] is used to obtain a value sometime in the future. Receivers of a | 8 * A [Future] represents a delayed computation. It is used to obtain a not-yet |
9 * [Future] can obtain the value by passing a callback to [then]. For example: | 9 * available value, or error, sometime in the future. Receivers of a |
10 * [Future] can register callbacks that handle the value or error once it is | |
11 * available. For example: | |
10 * | 12 * |
11 * Future<int> future = getFutureFromSomewhere(); | 13 * Future<int> future = getFuture(); |
12 * future.then((value) { | 14 * future.then((value) { |
13 * print("I received the number $value"); | 15 * print("I received the number $value"); |
14 * }); | 16 * }); |
15 * | 17 * |
16 * A future may complete by *succeeding* (producing a value) or *failing* | 18 * A [Future] can be completed in two ways: with a value ("the future succeeds") |
17 * (producing an error, which may be handled with [catchError]). | 19 * or with an error ("the future fails"). Users can install callbacks for each |
20 * case. The result of registering a pair of callbacks is a new Future (the | |
21 * "successor") which in turn is completed with the result of invoking the | |
22 * corresponding callback. The successor is completed with an error if the | |
23 * invoked callback throws. For example: | |
18 * | 24 * |
19 * When a future completes, the following actions happen in order: | 25 * Future<int> successor = future.then((int value) { |
nweiz
2013/01/11 19:55:06
Nit: indent this line +2 spaces
floitsch
2013/01/11 20:46:09
Done.
| |
26 * // Invoked when the future is completed with a value. | |
27 * return 42; // The successor is completed with the value 42. | |
28 * }, | |
29 * onError: (AsyncError e) { | |
30 * // Invoked when the future is completed with an error. | |
31 * if (canHandle(e)) { | |
32 * return 499; // The successor is completed with the value 499. | |
33 * } else { | |
34 * throw e; // The successor is completed with the error e. | |
35 * } | |
36 * }); | |
nweiz
2013/01/11 19:55:06
It would be nice to make the first error-handling
floitsch
2013/01/11 20:46:09
Added a catchError in the first example.
nweiz
2013/01/11 21:39:06
As I mentioned offline, I think it's important to
| |
20 * | 37 * |
21 * 1. if the future suceeded, handlers registered with [then] are called. | 38 * If a future does not have a successor but is completed with an error, it |
22 * 2. if the future failed, handlers registered with [catchError] are | 39 * forwards the error message to the global error-handler. This special casing |
23 * tested in sequence. Each test returning true is, have its handler | 40 * makes sure that no error is silently dropped. However, it also means that |
24 * called. | 41 * error handlers should be installed early, so that they are present as soon |
25 * 4. if the future failed, and no handler registered with [catchError] it | 42 * as a future is completed with an error. The following example demonstrates |
26 * is accepting the error, an error is sent to the global error handler. | 43 * this potential bug: |
27 * | 44 * |
28 * [Future]s are usually not created directly, but with [Completer]s. | 45 * var future = getFuture(); |
nweiz
2013/01/11 19:55:06
Nit: I think this whole block (and the ones below)
floitsch
2013/01/11 20:46:09
Done.
| |
46 * new Timer(5, (_) { | |
47 * // The error-handler is only attached 5ms after the future has been | |
48 * // received. If the future fails in the mean-time it will forward the | |
49 * // error to the global error-handler, even though there is code (just | |
50 * // below) to handle the error. | |
51 * future.then((value) { useValue(value); }, | |
52 * onError: (e) { handleError(e); }); | |
53 * }); | |
54 * | |
55 * In general we discourage registering the two callbacks at the same time, but | |
56 * prefer to use [then] with one argument (the value handler), and to use | |
57 * [catchError] for handling errors. The missing callbacks (the error-handler | |
58 * for [then], and the value-handler for [catchError]), are automatically | |
59 * configured to "forward" the value/error. Separating value and error-handling | |
60 * into separate registration calls usually leads to code that is easier to | |
61 * reason about. In fact it makes asynchronous code very similar to synchronous | |
62 * code: | |
63 * | |
64 * // Synchronous code. | |
65 * try { | |
66 * int value = foo(); | |
67 * return bar(value); | |
68 * } catch (e) { | |
69 * return 499; | |
70 * } | |
71 * | |
72 * Equivalent asynchronous code, based on futures: | |
73 * | |
74 * Future<int> future = foo(); // foo now returns a future. | |
75 * future.then((int value) => bar(value)) | |
76 * .catchError((e) => 499); | |
77 * | |
78 * Similar to the synchronous code, the error handler (registered with | |
79 * [catchError]) is handling the errors for exceptions coming from calls to | |
80 * 'foo', as well as 'bar'. This would not be the case if the error-handler was | |
81 * registered at the same time as the value-handler. | |
82 * | |
83 * Futures can have more than one callback-pairs registered. Each successor is | |
84 * treated independently and is handled as if it was the only successor. | |
29 */ | 85 */ |
86 // TODO(floitsch): document chaining. | |
30 abstract class Future<T> { | 87 abstract class Future<T> { |
31 /** A future whose value is immediately available. */ | 88 /** |
89 * A future whose value is immediately available. | |
nweiz
2013/01/11 19:55:06
This is a little misleading, since the event loop
floitsch
2013/01/11 20:46:09
Done.
| |
90 * | |
91 * See [Completer]s, for futures with values that are computed asynchronously. | |
92 */ | |
32 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value); | 93 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value); |
33 | 94 |
34 /** A future that completes with an error. */ | 95 /** |
96 * A future that completes with an error. | |
97 * | |
98 * See [Completer]s, for futures with values that are computed asynchronously. | |
99 */ | |
35 factory Future.immediateError(var error, [Object stackTrace]) { | 100 factory Future.immediateError(var error, [Object stackTrace]) { |
36 return new _FutureImpl<T>.immediateError(error, stackTrace); | 101 return new _FutureImpl<T>.immediateError(error, stackTrace); |
37 } | 102 } |
38 | 103 |
39 /** | 104 /** |
40 * Creates a future that completes after a delay. | 105 * Creates a future that completes after a delay. |
41 * | 106 * |
42 * The future will be completed after [milliseconds] have passed with | 107 * The future will be completed after [milliseconds] have passed with |
43 * the result of calling [value]. | 108 * the result of calling [value]. |
44 * | 109 * |
45 * If calling [value] throws, the created future will complete with the | 110 * If calling [value] throws, the created future will complete with the |
46 * error. | 111 * error. |
112 * | |
113 * See [Completer]s, for futures with values that are computed asynchronously. | |
47 */ | 114 */ |
48 factory Future.delayed(int milliseconds, T value()) { | 115 factory Future.delayed(int milliseconds, T value()) { |
49 _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value()); | 116 _FutureImpl<T> future = new _ThenFuture<dynamic, T>((_) => value()); |
50 new Timer(milliseconds, (_) => future._sendValue(null)); | 117 new Timer(milliseconds, (_) => future._sendValue(null)); |
51 return future; | 118 return future; |
52 } | 119 } |
53 | 120 |
54 /** | 121 /** |
55 * Wait for all the given futures to complete and collect their values. | 122 * Wait for all the given futures to complete and collect their values. |
56 * | 123 * |
57 * Returns a future which will complete once all the futures in a list are | 124 * Returns a future which will complete once all the futures in a list are |
58 * complete. If any of the futures in the list completes with an exception, | 125 * complete. If any of the futures in the list completes with an error, |
59 * the resulting future also completes with an exception. Otherwise the value | 126 * the resulting future also completes with an error. Otherwise the value |
60 * of the returned future will be a list of all the values that were produced. | 127 * of the returned future will be a list of all the values that were produced. |
61 */ | 128 */ |
62 static Future<List> wait(Iterable<Future> futures) { | 129 static Future<List> wait(Iterable<Future> futures) { |
63 return new _FutureImpl<List>.wait(futures); | 130 return new _FutureImpl<List>.wait(futures); |
64 } | 131 } |
65 | 132 |
66 /** | 133 /** |
67 * Perform an async operation for each element of the iterable, in turn. | 134 * Perform an async operation for each element of the iterable, in turn. |
68 * | 135 * |
69 * Runs [f] for each element in [input] in order, moving to the next element | 136 * Runs [f] for each element in [input] in order, moving to the next element |
(...skipping 15 matching lines...) Expand all Loading... | |
85 } | 152 } |
86 nextElement(null); | 153 nextElement(null); |
87 return doneSignal; | 154 return doneSignal; |
88 } | 155 } |
89 | 156 |
90 /** | 157 /** |
91 * When this future completes with a value, then [onValue] is called with this | 158 * When this future completes with a value, then [onValue] is called with this |
92 * value. If [this] future is already completed then the invocation of | 159 * value. If [this] future is already completed then the invocation of |
93 * [onValue] is delayed until the next event-loop iteration. | 160 * [onValue] is delayed until the next event-loop iteration. |
94 * | 161 * |
95 * Returns a new [Future] [:f:]. | 162 * Returns a new [Future] [:f:] which is completed with the result of |
nweiz
2013/01/11 19:55:06
I don't think Dartdoc's formatter understands "[Fu
floitsch
2013/01/11 20:46:09
Pretty sure it does. Will update if not.
nweiz
2013/01/11 21:39:06
You can see in the existing docs that it's not wor
floitsch
2013/01/11 22:39:48
Done.
| |
163 * invoking [onValue] (if [this] is completed with a value) or [onError] (if | |
164 * [this] is completed with an error). | |
96 * | 165 * |
97 * If [this] is completed with an error then [:f:] is completed with the same | 166 * If the invoked callback throws an exception, the returned future [:f:] is |
98 * error. If [this] is completed with a value, then [:f:]'s completion value | 167 * completed with the error. If the value thrown is an [AsyncError], it is |
99 * depends on the result of invoking [onValue] with [this]' completion value. | 168 * used directly, as the error result, otherwise it is wrapped in an |
nweiz
2013/01/11 19:55:06
Nit: "result, otherwise" -> "result. Otherwise"
floitsch
2013/01/11 20:46:09
Done.
| |
169 * [AsyncError] first. | |
100 * | 170 * |
101 * If [onValue] returns a [Future] [:f2:] then [:f:] and [:f2:] are chained. | 171 * If the invoked callback returns a [Future] [:f2:] then [:f:] and [:f2:] are |
102 * That is, [:f:] is completed with the completion value of [:f2:]. | 172 * chained. That is, [:f:] is completed with the completion value of [:f2:]. |
103 * | 173 * |
104 * Otherwise [:f:] is completed with the return value of [onValue]. | 174 * If [onError] is not given, it is equivalent to [:(e) { throw e; }:]. That |
105 * | 175 * is, it forwards the error. |
nweiz
2013/01/11 19:55:06
"forwards the error to the top-level exception han
floitsch
2013/01/11 20:46:09
No. to [:f:].
done.
| |
106 * If [onValue] throws an exception, the returned future will receive the | |
107 * exception. If the value thrown is an [AsyncError], it is used directly, | |
108 * as the error result, otherwise it is wrapped in an [AsyncError] first. | |
109 * | |
110 * If [onError] is provided, it is called if this future completes with an | |
111 * error, and its return value/throw behavior is handled the same way as | |
112 * for [catchError] without a [:test:] argument. | |
113 * | 176 * |
114 * In most cases, it is more readable to use [catchError] separately, possibly | 177 * In most cases, it is more readable to use [catchError] separately, possibly |
115 * with a [:test:] parameter, instead of handling both value and error in a | 178 * with a [:test:] parameter, instead of handling both value and error in a |
116 * single [then] call. | 179 * single [then] call. |
117 */ | 180 */ |
118 Future then(onValue(T value), { onError(AsyncError asyncError) }); | 181 Future then(onValue(T value), { onError(AsyncError asyncError) }); |
119 | 182 |
120 /** | 183 /** |
121 * Handles errors emitted by this [Future]. | 184 * Handles errors emitted by this [Future]. |
122 * | 185 * |
123 * When this future completes with an error, first [test] is called with the | 186 * When [this] completes with a value, the value is forwarded to [this]' |
nweiz
2013/01/11 19:55:06
Nit: "[this]'" -> "[this]'s"
floitsch
2013/01/11 20:46:09
Done.
| |
124 * error's value. | 187 * successor unmodified. |
nweiz
2013/01/11 19:55:06
It's confusing that in the documentation for then(
floitsch
2013/01/11 20:46:09
Done.
| |
125 * | 188 * |
126 * If [test] returns [true], [onError] is called with the error | 189 * When [this] completes with an error, [test] is called with the |
127 * wrapped in an [AsyncError]. The result of [onError] is handled exactly as | 190 * error's value. If the invocation returns [true], [onError] is called with |
128 * [then]'s [onValue]. | 191 * the error wrapped in an [AsyncError]. The result of [onError] is handled |
192 * exactly the same as for [then]'s [onError]. | |
129 * | 193 * |
130 * If [test] returns false, the exception is not handled by [onError], but is | 194 * If [test] returns false, the exception is not handled by [onError], but is |
131 * emitted by the returned Future unmodified. | 195 * thrown unmodified, thus passing it on [this]' successor. |
132 * | 196 * |
133 * If [test] is omitted, it defaults to a function that always returns true. | 197 * If [test] is omitted, it defaults to a function that always returns true. |
134 * | 198 * |
135 * Example: | 199 * Example: |
nweiz
2013/01/11 19:55:06
There should be a newline after this line, and the
floitsch
2013/01/11 20:46:09
Done.
| |
136 * foo | 200 * foo |
137 * .catchError(..., test: (e) => e is ArgumentError) | 201 * .catchError(..., test: (e) => e is ArgumentError) |
138 * .catchError(..., test: (e) => e is NoSuchMethodError) | 202 * .catchError(..., test: (e) => e is NoSuchMethodError) |
139 * .then((v) { ... }); | 203 * .then((v) { ... }); |
204 * | |
205 * This method is equivalent to: | |
206 * | |
207 * Future catchError(onError(AsyncError asyncError), | |
208 * {bool test(Object error)}) { | |
209 * this.then((v) => v, // Forward the value. | |
210 * // But handle errors, if the [test] succeeds. | |
211 * onError: (AsyncError e) { | |
212 * if (test == null || test(e.error)) { | |
213 * return onError(e); | |
214 * } | |
215 * throw e; | |
216 * }); | |
217 * } | |
218 * | |
140 */ | 219 */ |
141 Future catchError(onError(AsyncError asyncError), | 220 Future catchError(onError(AsyncError asyncError), |
142 {bool test(Object error)}); | 221 {bool test(Object error)}); |
143 | 222 |
144 /** | 223 /** |
145 * Register a function to be called when this future completes. | 224 * Register a function to be called when this future completes. |
146 * | 225 * |
147 * The [action] function is called when this future completes, whether it | 226 * The [action] function is called when this future completes, whether it |
148 * does so with a value or with an error. | 227 * does so with a value or with an error. |
149 * | 228 * |
150 * This is the asynchronous equivalent of a "finally" block. | 229 * This is the asynchronous equivalent of a "finally" block. |
151 * | 230 * |
152 * The future returned by this call, [:f:], will complete the same way | 231 * The future returned by this call, [:f:], will complete the same way |
153 * as this future unless an error occurs in the [action] call, or in | 232 * as this future unless an error occurs in the [action] call, or in |
154 * a [Future] returned by the [action] call. If the call to [action] | 233 * a [Future] returned by the [action] call. If the call to [action] |
155 * does not return a future, its return value is ignored. | 234 * does not return a future, its return value is ignored. |
156 * | 235 * |
157 * If the call to [action] throws, then [:f:] is completed with the | 236 * If the call to [action] throws, then [:f:] is completed with the |
158 * thrown error. | 237 * thrown error. |
159 * | 238 * |
160 * If the call to [action] returns a [Future], [:f2:], then completion of | 239 * If the call to [action] returns a [Future], [:f2:], then completion of |
161 * [:f:] is delayed until [:f2:] completes. If [:f2:] completes with | 240 * [:f:] is delayed until [:f2:] completes. If [:f2:] completes with |
162 * an error, that will be the result of [:f:] too. | 241 * an error, that will be the result of [:f:] too. |
242 * | |
243 * This method is equivalent to: | |
244 * | |
245 * Future<T> whenComplete(action()) { | |
246 * this.then((v) { | |
247 * action(); | |
248 * return v | |
249 * }, | |
250 * onError: (AsyncError e) { | |
nweiz
2013/01/11 19:55:06
This is another place where it would be nice to us
floitsch
2013/01/11 20:46:09
Not possible, since it would change the semantics.
nweiz
2013/01/11 21:39:06
Not if catchError() comes before then().
floitsch
2013/01/11 22:39:48
point taken.
For now I will leave it as is. I will
| |
251 * action(); | |
252 * throw e; | |
253 * }); | |
254 * } | |
163 */ | 255 */ |
164 Future<T> whenComplete(action()); | 256 Future<T> whenComplete(action()); |
165 | 257 |
166 /** | 258 /** |
167 * Creates a [Stream] that sends [this]' completion value, data or error, to | 259 * Creates a [Stream] that sends [this]' completion value, data or error, to |
168 * its subscribers. The stream closes after the completion value. | 260 * its subscribers. The stream closes after the completion value. |
169 */ | 261 */ |
170 Stream<T> asStream(); | 262 Stream<T> asStream(); |
171 } | 263 } |
172 | 264 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 * The argument [exception] should not be [:null:]. | 305 * The argument [exception] should not be [:null:]. |
214 * | 306 * |
215 * If [exception] is an [AsyncError], it is used directly as the error | 307 * If [exception] is an [AsyncError], it is used directly as the error |
216 * message sent to the future's listeners, and [stackTrace] is ignored. | 308 * message sent to the future's listeners, and [stackTrace] is ignored. |
217 * | 309 * |
218 * Otherwise the [exception] and an optional [stackTrace] is combined into an | 310 * Otherwise the [exception] and an optional [stackTrace] is combined into an |
219 * [AsyncError] and sent to this future's listeners. | 311 * [AsyncError] and sent to this future's listeners. |
220 */ | 312 */ |
221 void completeError(Object exception, [Object stackTrace]); | 313 void completeError(Object exception, [Object stackTrace]); |
222 } | 314 } |
OLD | NEW |