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] represents a delayed computation. It is used to obtain a not-yet | 8 * A [Future] represents a delayed computation. It is used to obtain a not-yet |
9 * available value, or error, sometime in the future. Receivers of a | 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 | 10 * [Future] can register callbacks that handle the value or error once it is |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 * Similar to the synchronous code, the error handler (registered with | 77 * Similar to the synchronous code, the error handler (registered with |
78 * [catchError]) is handling the errors for exceptions coming from calls to | 78 * [catchError]) is handling the errors for exceptions coming from calls to |
79 * 'foo', as well as 'bar'. This would not be the case if the error-handler was | 79 * 'foo', as well as 'bar'. This would not be the case if the error-handler was |
80 * registered at the same time as the value-handler. | 80 * registered at the same time as the value-handler. |
81 * | 81 * |
82 * Futures can have more than one callback-pairs registered. Each successor is | 82 * Futures can have more than one callback-pairs registered. Each successor is |
83 * treated independently and is handled as if it was the only successor. | 83 * treated independently and is handled as if it was the only successor. |
84 */ | 84 */ |
85 // TODO(floitsch): document chaining. | 85 // TODO(floitsch): document chaining. |
86 abstract class Future<T> { | 86 abstract class Future<T> { |
| 87 |
87 /** | 88 /** |
88 * Creates a future containing the result of calling [function]. | 89 * Creates a future containing the result of calling [computation] |
| 90 * asynchronously with [runAsync]. |
89 * | 91 * |
90 * The result of computing [:function():] is either a returned value or | 92 * if the result of executing [computation] throws, the returned future is |
91 * a throw. | 93 * completed with the error. If a thrown value is an [AsyncError], it is used |
| 94 * directly, instead of wrapping this error again in another [AsyncError]. |
| 95 * |
| 96 * If the returned value is itself a [Future], completion of |
| 97 * the created future will wait until the returned future completes, |
| 98 * and will then complete with the same result. |
92 * | 99 * |
93 * If a value is returned, it becomes the result of the created future. | 100 * If a value is returned, it becomes the result of the created future. |
| 101 */ |
| 102 factory Future(computation()) { |
| 103 _ThenFuture<dynamic, T> future = |
| 104 new _ThenFuture<dynamic, T>((_) => computation()); |
| 105 runAsync(() => future._sendValue(null)); |
| 106 return future; |
| 107 } |
| 108 |
| 109 /** |
| 110 * Creates a future containing the result of immediately calling |
| 111 * [computation]. |
94 * | 112 * |
95 * If calling [function] throws, the created [Future] will be completed | 113 * if the result of executing [computation] throws, the returned future is |
96 * with an async error containing the thrown value and a captured | 114 * completed with the error. If a thrown value is an [AsyncError], it is used |
97 * stacktrace. | 115 * directly, instead of wrapping this error again in another [AsyncError]. |
98 * | |
99 * However, if the result of calling [function] is already an asynchronous | |
100 * result, we treat it specially. | |
101 * | 116 * |
102 * If the returned value is itself a [Future], completion of | 117 * If the returned value is itself a [Future], completion of |
103 * the created future will wait until the returned future completes, | 118 * the created future will wait until the returned future completes, |
104 * and will then complete with the same result. | 119 * and will then complete with the same result. |
105 */ | 120 */ |
106 factory Future.of(function()) { | 121 factory Future.sync(computation()) { |
107 try { | 122 try { |
108 var result = function(); | 123 var result = computation(); |
109 return new _FutureImpl<T>().._setOrChainValue(result); | 124 return new _FutureImpl<T>().._setOrChainValue(result); |
110 } catch (error, stackTrace) { | 125 } catch (error, stackTrace) { |
111 return new _FutureImpl<T>.immediateError(error, stackTrace); | 126 return new _FutureImpl<T>.immediateError(error, stackTrace); |
112 } | 127 } |
113 } | 128 } |
114 | 129 |
115 /** | 130 /** |
116 * A future whose value is available in the next event-loop iteration. | 131 * A future whose value is available in the next event-loop iteration. |
117 * | 132 * |
118 * If [value] is not a [Future], using this constructor is equivalent | 133 * If [value] is not a [Future], using this constructor is equivalent |
119 * to [:new Future.of(() => value):]. | 134 * to [:new Future.sync(() => value):]. |
120 * | 135 * |
121 * See [Completer] to create a Future and complete it later. | 136 * See [Completer] to create a Future and complete it later. |
122 */ | 137 */ |
123 factory Future.immediate(T value) => new _FutureImpl<T>.immediate(value); | 138 factory Future.value([T value]) => new _FutureImpl<T>.immediate(value); |
124 | 139 |
125 /** | 140 /** |
126 * A future that completes with an error in the next event-loop iteration. | 141 * A future that completes with an error in the next event-loop iteration. |
127 * | 142 * |
128 * See [Completer] to create a Future and complete it later. | 143 * See [Completer] to create a Future and complete it later. |
129 */ | 144 */ |
130 factory Future.immediateError(var error, [Object stackTrace]) { | 145 factory Future.error(var error, [Object stackTrace]) { |
131 return new _FutureImpl<T>.immediateError(error, stackTrace); | 146 return new _FutureImpl<T>.immediateError(error, stackTrace); |
132 } | 147 } |
133 | 148 |
134 /** | 149 /** |
135 * Creates a future that completes after a delay. | 150 * Creates a future that completes after a delay. |
136 * | 151 * |
137 * The future will be completed after the given [duration] has passed with | 152 * The future will be completed after the given [duration] has passed with |
138 * the result of calling [computation]. If the duration is 0 or less, it | 153 * the result of calling [computation]. If the duration is 0 or less, it |
139 * completes no sooner than in the next event-loop iteration. | 154 * completes no sooner than in the next event-loop iteration. |
140 * | 155 * |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 * completes when all elements have been processed. | 192 * completes when all elements have been processed. |
178 * | 193 * |
179 * The return values of all [Future]s are discarded. Any errors will cause the | 194 * The return values of all [Future]s are discarded. Any errors will cause the |
180 * iteration to stop and will be piped through the returned [Future]. | 195 * iteration to stop and will be piped through the returned [Future]. |
181 */ | 196 */ |
182 static Future forEach(Iterable input, Future f(element)) { | 197 static Future forEach(Iterable input, Future f(element)) { |
183 _FutureImpl doneSignal = new _FutureImpl(); | 198 _FutureImpl doneSignal = new _FutureImpl(); |
184 Iterator iterator = input.iterator; | 199 Iterator iterator = input.iterator; |
185 void nextElement(_) { | 200 void nextElement(_) { |
186 if (iterator.moveNext()) { | 201 if (iterator.moveNext()) { |
187 new Future.of(() => f(iterator.current)) | 202 new Future.sync(() => f(iterator.current)) |
188 .then(nextElement, onError: doneSignal._setError); | 203 .then(nextElement, onError: doneSignal._setError); |
189 } else { | 204 } else { |
190 doneSignal._setValue(null); | 205 doneSignal._setValue(null); |
191 } | 206 } |
192 } | 207 } |
193 nextElement(null); | 208 nextElement(null); |
194 return doneSignal; | 209 return doneSignal; |
195 } | 210 } |
196 | 211 |
197 /** | 212 /** |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 * | 363 * |
349 * The argument [exception] should not be `null`. | 364 * The argument [exception] should not be `null`. |
350 */ | 365 */ |
351 void completeError(Object exception, [Object stackTrace]); | 366 void completeError(Object exception, [Object stackTrace]); |
352 | 367 |
353 /** | 368 /** |
354 * Whether the future has been completed. | 369 * Whether the future has been completed. |
355 */ | 370 */ |
356 bool get isCompleted; | 371 bool get isCompleted; |
357 } | 372 } |
OLD | NEW |