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

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

Issue 2917683002: Clean-up of Future documentation and small fix-ups. (Closed)
Patch Set: address comments Created 3 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
« no previous file with comments | « no previous file | sdk/lib/async/stream.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 /// A type representing values that are either `Future<T>` or `T`. 7 /// A type representing values that are either `Future<T>` or `T`.
8 /// 8 ///
9 /// This class declaration is a public stand-in for an internal 9 /// This class declaration is a public stand-in for an internal
10 /// future-or-value generic type. References to this class are resolved to the 10 /// future-or-value generic type. References to this class are resolved to the
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 * A [Future] is used to represent a potential value, or error, 50 * A [Future] is used to represent a potential value, or error,
51 * that will be available at some time in the future. 51 * that will be available at some time in the future.
52 * Receivers of a [Future] can register callbacks 52 * Receivers of a [Future] can register callbacks
53 * that handle the value or error once it is available. 53 * that handle the value or error once it is available.
54 * For example: 54 * For example:
55 * 55 *
56 * Future<int> future = getFuture(); 56 * Future<int> future = getFuture();
57 * future.then((value) => handleValue(value)) 57 * future.then((value) => handleValue(value))
58 * .catchError((error) => handleError(error)); 58 * .catchError((error) => handleError(error));
59 * 59 *
60 * A [Future] can complete in two ways: 60 * A [Future] can be completed in two ways:
61 * with a value ("the future succeeds") 61 * with a value ("the future succeeds")
62 * or with an error ("the future fails"). 62 * or with an error ("the future fails").
63 * Users can install callbacks for each case. 63 * Users can install callbacks for each case.
64 *
65 * In some cases we say that a future is completed with another future.
66 * This is a short way of stating that the future is completed in the same way,
67 * with the same value or error,
68 * as the other future once that completes.
69 * Whenever a function in the core library may complete a future
70 * (for example [Completer.complete] or [new Future.value]),
71 * then it also accepts another future and does this work for the developer.
72 *
64 * The result of registering a pair of callbacks is a new Future (the 73 * The result of registering a pair of callbacks is a new Future (the
65 * "successor") which in turn is completed with the result of invoking the 74 * "successor") which in turn is completed with the result of invoking the
66 * corresponding callback. 75 * corresponding callback.
67 * The successor is completed with an error if the invoked callback throws. 76 * The successor is completed with an error if the invoked callback throws.
68 * For example: 77 * For example:
69 * 78 * ```
70 * Future<int> successor = future.then((int value) { 79 * Future<int> successor = future.then((int value) {
71 * // Invoked when the future is completed with a value. 80 * // Invoked when the future is completed with a value.
72 * return 42; // The successor is completed with the value 42. 81 * return 42; // The successor is completed with the value 42.
73 * }, 82 * },
74 * onError: (e) { 83 * onError: (e) {
75 * // Invoked when the future is completed with an error. 84 * // Invoked when the future is completed with an error.
76 * if (canHandle(e)) { 85 * if (canHandle(e)) {
77 * return 499; // The successor is completed with the value 499. 86 * return 499; // The successor is completed with the value 499.
78 * } else { 87 * } else {
79 * throw e; // The successor is completed with the error e. 88 * throw e; // The successor is completed with the error e.
80 * } 89 * }
81 * }); 90 * });
91 * ```
82 * 92 *
83 * If a future does not have a successor when it completes with an error, 93 * If a future does not have a successor when it completes with an error,
84 * it forwards the error message to the global error-handler. 94 * it forwards the error message to the global error-handler.
85 * This behavior makes sure that no error is silently dropped. 95 * This behavior makes sure that no error is silently dropped.
86 * However, it also means that error handlers should be installed early, 96 * However, it also means that error handlers should be installed early,
87 * so that they are present as soon as a future is completed with an error. 97 * so that they are present as soon as a future is completed with an error.
88 * The following example demonstrates this potential bug: 98 * The following example demonstrates this potential bug:
89 * 99 * ```
90 * var future = getFuture(); 100 * var future = getFuture();
91 * new Timer(new Duration(milliseconds: 5), () { 101 * new Timer(new Duration(milliseconds: 5), () {
92 * // The error-handler is not attached until 5 ms after the future has 102 * // The error-handler is not attached until 5 ms after the future has
93 * // been received. If the future fails before that, the error is 103 * // been received. If the future fails before that, the error is
94 * // forwarded to the global error-handler, even though there is code 104 * // forwarded to the global error-handler, even though there is code
95 * // (just below) to eventually handle the error. 105 * // (just below) to eventually handle the error.
96 * future.then((value) { useValue(value); }, 106 * future.then((value) { useValue(value); },
97 * onError: (e) { handleError(e); }); 107 * onError: (e) { handleError(e); });
98 * }); 108 * });
109 * ```
99 * 110 *
100 * When registering callbacks, it's often more readable to register the two 111 * When registering callbacks, it's often more readable to register the two
101 * callbacks separately, by first using [then] with one argument 112 * callbacks separately, by first using [then] with one argument
102 * (the value handler) and using a second [catchError] for handling errors. 113 * (the value handler) and using a second [catchError] for handling errors.
103 * Each of these will forward the result that they don't handle 114 * Each of these will forward the result that they don't handle
104 * to their successors, and together they handle both value and error result. 115 * to their successors, and together they handle both value and error result.
105 * It also has the additional benefit of the [catchError] handling errors in the 116 * It also has the additional benefit of the [catchError] handling errors in the
106 * [then] value callback too. 117 * [then] value callback too.
107 * Using sequential handlers instead of parallel ones often leads to code that 118 * Using sequential handlers instead of parallel ones often leads to code that
108 * is easier to reason about. 119 * is easier to reason about.
109 * It also makes asynchronous code very similar to synchronous code: 120 * It also makes asynchronous code very similar to synchronous code:
110 * 121 * ```
111 * // Synchronous code. 122 * // Synchronous code.
112 * try { 123 * try {
113 * int value = foo(); 124 * int value = foo();
114 * return bar(value); 125 * return bar(value);
115 * } catch (e) { 126 * } catch (e) {
116 * return 499; 127 * return 499;
117 * } 128 * }
129 * ```
118 * 130 *
119 * Equivalent asynchronous code, based on futures: 131 * Equivalent asynchronous code, based on futures:
120 * 132 * ```
121 * Future<int> future = new Future(foo); // Result of foo() as a future. 133 * Future<int> future = new Future(foo); // Result of foo() as a future.
122 * future.then((int value) => bar(value)) 134 * future.then((int value) => bar(value))
123 * .catchError((e) => 499); 135 * .catchError((e) => 499);
136 * ```
124 * 137 *
125 * Similar to the synchronous code, the error handler (registered with 138 * Similar to the synchronous code, the error handler (registered with
126 * [catchError]) is handling any errors thrown by either `foo` or `bar`. 139 * [catchError]) is handling any errors thrown by either `foo` or `bar`.
127 * If the error-handler had been registered as the `onError` parameter of 140 * If the error-handler had been registered as the `onError` parameter of
128 * the `then` call, it would not catch errors from the `bar` call. 141 * the `then` call, it would not catch errors from the `bar` call.
129 * 142 *
130 * Futures can have more than one callback-pair registered. Each successor is 143 * Futures can have more than one callback-pair registered. Each successor is
131 * treated independently and is handled as if it was the only successor. 144 * treated independently and is handled as if it was the only successor.
132 * 145 *
133 * A future may also fail to ever complete. In that case, no callbacks are 146 * A future may also fail to ever complete. In that case, no callbacks are
134 * called. 147 * called.
135 */ 148 */
136 abstract class Future<T> { 149 abstract class Future<T> {
137 // The `_nullFuture` is a completed Future with the value `null`. 150 /// A `Future<Null>` completed with `null`.
138 static final _Future<Null> _nullFuture = new _Future<Null>.value(null); 151 static final _Future<Null> _nullFuture = new _Future<Null>.value(null);
139 152
153 /// A `Future<bool>` completed with `false`.
154 static final _Future<bool> _falseFuture = new _Future<bool>.value(false);
155
140 /** 156 /**
141 * Creates a future containing the result of calling [computation] 157 * Creates a future containing the result of calling [computation]
142 * asynchronously with [Timer.run]. 158 * asynchronously with [Timer.run].
143 * 159 *
144 * If the result of executing [computation] throws, the returned future is 160 * If the result of executing [computation] throws, the returned future is
145 * completed with the error. 161 * completed with the error.
146 * 162 *
147 * If the returned value is itself a [Future], completion of 163 * If the returned value is itself a [Future], completion of
148 * the created future will wait until the returned future completes, 164 * the created future will wait until the returned future completes,
149 * and will then complete with the same result. 165 * and will then complete with the same result.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 future._asyncCompleteError( 235 future._asyncCompleteError(
220 _nonNullError(replacement.error), replacement.stackTrace); 236 _nonNullError(replacement.error), replacement.stackTrace);
221 } else { 237 } else {
222 future._asyncCompleteError(error, stackTrace); 238 future._asyncCompleteError(error, stackTrace);
223 } 239 }
224 return future; 240 return future;
225 } 241 }
226 } 242 }
227 243
228 /** 244 /**
229 * A future whose value is available in the next event-loop iteration. 245 * Creates a future completed with [value].
230 * 246 *
231 * If [result] is not a [Future], using this constructor is equivalent 247 * If [value] is a future, the created future waits for the
232 * to `new Future<T>.sync(() => result)`. 248 * [value] future to complete, and then completes with the same result.
249 * Since a [value] future can complete with an error, so can the future
250 * created by [Future.value], even if the name suggests otherwise.
251 *
252 * If [value] is not a [Future], the created future is completed
253 * with the [value] value,
254 * equivalently to `new Future<T>.sync(() => value)`.
233 * 255 *
234 * Use [Completer] to create a future and complete it later. 256 * Use [Completer] to create a future and complete it later.
235 */ 257 */
236 factory Future.value([FutureOr<T> result]) { 258 factory Future.value([FutureOr<T> value]) {
237 return new _Future<T>.immediate(result); 259 return new _Future<T>.immediate(value);
238 } 260 }
239 261
240 /** 262 /**
241 * A future that completes with an error in the next event-loop iteration. 263 * Creates a future that completes with an error.
264 *
265 * The created future will be completed with an error in a future microtask.
266 * This allows enough time for someone to add an error handler on the future.
267 * If an error handler isn't added before the future completes, the error
268 * will be considered unhandled.
242 * 269 *
243 * If [error] is `null`, it is replaced by a [NullThrownError]. 270 * If [error] is `null`, it is replaced by a [NullThrownError].
244 * 271 *
245 * Use [Completer] to create a future and complete it later. 272 * Use [Completer] to create a future and complete it later.
246 */ 273 */
247 factory Future.error(Object error, [StackTrace stackTrace]) { 274 factory Future.error(Object error, [StackTrace stackTrace]) {
248 error = _nonNullError(error); 275 error = _nonNullError(error);
249 if (!identical(Zone.current, _ROOT_ZONE)) { 276 if (!identical(Zone.current, _ROOT_ZONE)) {
250 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); 277 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
251 if (replacement != null) { 278 if (replacement != null) {
252 error = _nonNullError(replacement.error); 279 error = _nonNullError(replacement.error);
253 stackTrace = replacement.stackTrace; 280 stackTrace = replacement.stackTrace;
254 } 281 }
255 } 282 }
256 return new _Future<T>.immediateError(error, stackTrace); 283 return new _Future<T>.immediateError(error, stackTrace);
257 } 284 }
258 285
259 /** 286 /**
260 * Creates a future that runs its computation after a delay. 287 * Creates a future that runs its computation after a delay.
261 * 288 *
262 * The [computation] will be executed after the given [duration] has passed, 289 * The [computation] will be executed after the given [duration] has passed,
263 * and the future is completed with the result. 290 * and the future is completed with the result of the computation,
291 *
264 * If the duration is 0 or less, 292 * If the duration is 0 or less,
265 * it completes no sooner than in the next event-loop iteration. 293 * it completes no sooner than in the next event-loop iteration,
294 * after all microtasks have run.
266 * 295 *
267 * If [computation] is omitted, 296 * If [computation] is omitted,
268 * it will be treated as if [computation] was set to `() => null`, 297 * it will be treated as if [computation] was `() => null`,
269 * and the future will eventually complete with the `null` value. 298 * and the future will eventually complete with the `null` value.
270 * 299 *
271 * If calling [computation] throws, the created future will complete with the 300 * If calling [computation] throws, the created future will complete with the
272 * error. 301 * error.
273 * 302 *
274 * See also [Completer] for a way to create and complete a future at a 303 * See also [Completer] for a way to create and complete a future at a
275 * later time that isn't necessarily after a known fixed duration. 304 * later time that isn't necessarily after a known fixed duration.
276 */ 305 */
277 factory Future.delayed(Duration duration, [FutureOr<T> computation()]) { 306 factory Future.delayed(Duration duration, [FutureOr<T> computation()]) {
278 _Future<T> result = new _Future<T>(); 307 _Future<T> result = new _Future<T>();
279 new Timer(duration, () { 308 new Timer(duration, () {
280 try { 309 try {
281 result._complete(computation?.call()); 310 result._complete(computation?.call());
282 } catch (e, s) { 311 } catch (e, s) {
283 _completeWithErrorCallback(result, e, s); 312 _completeWithErrorCallback(result, e, s);
284 } 313 }
285 }); 314 });
286 return result; 315 return result;
287 } 316 }
288 317
289 /** 318 /**
290 * Wait for all the given futures to complete and collect their values. 319 * Waits for multiple futures to complete and collects their results.
291 * 320 *
292 * Returns a future which will complete once all the futures in a list 321 * Returns a future which will complete once all the provided futures
293 * have completed. 322 * have completed, either with their results, or with an error if either
323 * of the provided futures fail.
294 * 324 *
295 * The value of the returned future will be a list of all the values that 325 * The value of the returned future will be a list of all the values that
296 * were produced. 326 * were produced.
297 * 327 *
298 * If any of the given futures completes with an error, then the returned 328 * If any future completes with an error,
299 * future completes with that error. If other futures complete with errors, 329 * then the returned future completes with that error.
300 * those errors are discarded. 330 * If further futures also complete with errors, those errors are discarded.
301 * 331 *
302 * If `eagerError` is true, the returned future completes with an error 332 * If `eagerError` is true, the returned future completes with an error
303 * immediately on the first error from one of the futures. Otherwise all 333 * immediately on the first error from one of the futures. Otherwise all
304 * futures must complete before the returned future is completed (still with 334 * futures must complete before the returned future is completed (still with
305 * the first error; the remaining errors are silently dropped). 335 * the first error; the remaining errors are silently dropped).
306 * 336 *
307 * In the case of an error, [cleanUp] (if provided), is invoked on any 337 * In the case of an error, [cleanUp] (if provided), is invoked on any
308 * non-null result of successful futures. 338 * non-null result of successful futures.
309 * This makes it posible to `cleanUp` resources that would otherwise be 339 * This makes it posible to `cleanUp` resources that would otherwise be
310 * lost (since the returned future does not provide access to these values). 340 * lost (since the returned future does not provide access to these values).
311 * The [cleanUp] function is unused if there is no error. 341 * The [cleanUp] function is unused if there is no error.
312 * 342 *
313 * The call to `cleanUp` should not throw. If it does, the error will be an 343 * The call to [cleanUp] should not throw. If it does, the error will be an
314 * uncaught asynchronous error. 344 * uncaught asynchronous error.
315 */ 345 */
316 static Future<List<T>> wait<T>(Iterable<Future<T>> futures, 346 static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
317 {bool eagerError: false, void cleanUp(T successValue)}) { 347 {bool eagerError: false, void cleanUp(T successValue)}) {
318 final _Future<List<T>> result = new _Future<List<T>>(); 348 final _Future<List<T>> result = new _Future<List<T>>();
319 List<T> values; // Collects the values. Set to null on error. 349 List<T> values; // Collects the values. Set to null on error.
320 int remaining = 0; // How many futures are we waiting for. 350 int remaining = 0; // How many futures are we waiting for.
321 var error; // The first error from a future. 351 var error; // The first error from a future.
322 StackTrace stackTrace; // The stackTrace that came with the error. 352 StackTrace stackTrace; // The stackTrace that came with the error.
323 353
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 stackTrace = st; 431 stackTrace = st;
402 } 432 }
403 } 433 }
404 return result; 434 return result;
405 } 435 }
406 436
407 /** 437 /**
408 * Returns the result of the first future in [futures] to complete. 438 * Returns the result of the first future in [futures] to complete.
409 * 439 *
410 * The returned future is completed with the result of the first 440 * The returned future is completed with the result of the first
411 * future in [futures] to report that it is complete. 441 * future in [futures] to report that it is complete,
442 * whether it's with a value or an error.
412 * The results of all the other futures are discarded. 443 * The results of all the other futures are discarded.
413 * 444 *
414 * If [futures] is empty, or if none of its futures complete, 445 * If [futures] is empty, or if none of its futures complete,
415 * the returned future never completes. 446 * the returned future never completes.
416 */ 447 */
417 static Future<T> any<T>(Iterable<Future<T>> futures) { 448 static Future<T> any<T>(Iterable<Future<T>> futures) {
418 var completer = new Completer<T>.sync(); 449 var completer = new Completer<T>.sync();
419 var onValue = (T value) { 450 var onValue = (T value) {
420 if (!completer.isCompleted) completer.complete(value); 451 if (!completer.isCompleted) completer.complete(value);
421 }; 452 };
422 var onError = (error, stack) { 453 var onError = (error, stack) {
423 if (!completer.isCompleted) completer.completeError(error, stack); 454 if (!completer.isCompleted) completer.completeError(error, stack);
424 }; 455 };
425 for (var future in futures) { 456 for (var future in futures) {
426 future.then(onValue, onError: onError); 457 future.then(onValue, onError: onError);
427 } 458 }
428 return completer.future; 459 return completer.future;
429 } 460 }
430 461
431 /** 462 /**
432 * Perform an operation for each element of the iterable, in turn. 463 * Performs an action for each element of the iterable, in turn.
433 * 464 *
434 * The operation, [f], may be either synchronous or asynchronous. 465 * The [action] may be either synchronous or asynchronous.
435 * 466 *
436 * Calls [f] with each element in [input] in order. 467 * Calls [action] with each element in [elements] in order.
437 * If the call to [f] returns a `Future<T>`, the iteration waits 468 * If the call to [action] returns a `Future<T>`, the iteration waits
438 * until the future is completed before moving to the next element. 469 * until the future is completed before continuing with the next element.
439 * 470 *
440 * Returns a [Future] that completes with `null` when all elements have been 471 * Returns a [Future] that completes with `null` when all elements have been
441 * processed. 472 * processed.
442 * 473 *
443 * Non-[Future] return values, and completion-values of returned [Future]s, 474 * Non-[Future] return values, and completion-values of returned [Future]s,
444 * are discarded. 475 * are discarded.
445 * 476 *
446 * Any error from [f], synchronous or asynchronous, will stop the iteration 477 * Any error from [action], synchronous or asynchronous,
447 * and will be reported in the returned [Future]. 478 * will stop the iteration and be reported in the returned [Future].
448 */ 479 */
449 static Future forEach<T>(Iterable<T> input, FutureOr f(T element)) { 480 static Future forEach<T>(Iterable<T> elements, FutureOr action(T element)) {
450 var iterator = input.iterator; 481 var iterator = elements.iterator;
451 return doWhile(() { 482 return doWhile(() {
452 if (!iterator.moveNext()) return false; 483 if (!iterator.moveNext()) return false;
453 var result = f(iterator.current); 484 var result = action(iterator.current);
454 if (result is Future) return result.then(_kTrue); 485 if (result is Future) return result.then(_kTrue);
455 return true; 486 return true;
456 }); 487 });
457 } 488 }
458 489
459 // Constant `true` function, used as callback by [forEach]. 490 // Constant `true` function, used as callback by [forEach].
460 static bool _kTrue(_) => true; 491 static bool _kTrue(_) => true;
461 492
462 /** 493 /**
463 * Performs an operation repeatedly until it returns `false`. 494 * Performs an operation repeatedly until it returns `false`.
464 * 495 *
465 * The operation, [f], may be either synchronous or asynchronous. 496 * The operation, [f], may be either synchronous or asynchronous.
466 * 497 *
467 * The operation is called repeatedly as long as it returns either the [bool] 498 * The operation is called repeatedly as long as it returns either the [bool]
468 * value `true` or a `Future<bool>` which completes with the value `true`. 499 * value `true` or a `Future<bool>` which completes with the value `true`.
469 * 500 *
470 * If a call to [f] returns `false` or a [Future] that completes to `false`, 501 * If a call to [f] returns `false` or a [Future] that completes to `false`,
471 * iteration ends and the future returned by [doWhile] is completed with 502 * iteration ends and the future returned by [doWhile] is completed with
472 * a `null` value. 503 * a `null` value.
473 * 504 *
474 * If a call to [f] throws or a future returned by [f] completes with 505 * If a call to [f] throws or a future returned by [f] completes with
475 * an error, iteration ends and the future returned by [doWhile] 506 * an error, iteration ends and the future returned by [doWhile]
476 * completes with the same error. 507 * completes with the same error.
477 * 508 *
478 * Calls to [f] may happen at any time, including immediately after calling 509 * Calls to [action] may happen at any time,
479 * `doWhile`. The only restriction is a new call to [f] won't happen before 510 * including immediately after calling `doWhile`.
511 * The only restriction is a new call to [action] won't happen before
480 * the previous call has returned, and if it returned a `Future<bool>`, not 512 * the previous call has returned, and if it returned a `Future<bool>`, not
481 * until that future has completed. 513 * until that future has completed.
482 */ 514 */
483 static Future doWhile(FutureOr<bool> f()) { 515 static Future doWhile(FutureOr<bool> action()) {
484 _Future doneSignal = new _Future(); 516 _Future doneSignal = new _Future();
485 var nextIteration; 517 var nextIteration;
486 // Bind this callback explicitly so that each iteration isn't bound in the 518 // Bind this callback explicitly so that each iteration isn't bound in the
487 // context of all the previous iterations' callbacks. 519 // context of all the previous iterations' callbacks.
488 // This avoids, e.g., deeply nested stack traces from the stack trace 520 // This avoids, e.g., deeply nested stack traces from the stack trace
489 // package. 521 // package.
490 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) { 522 nextIteration = Zone.current.bindUnaryCallback((bool keepGoing) {
491 while (keepGoing) { 523 while (keepGoing) {
492 FutureOr<bool> result; 524 FutureOr<bool> result;
493 try { 525 try {
494 result = f(); 526 result = action();
495 } catch (error, stackTrace) { 527 } catch (error, stackTrace) {
496 // Cannot use _completeWithErrorCallback because it completes 528 // Cannot use _completeWithErrorCallback because it completes
497 // the future synchronously. 529 // the future synchronously.
498 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace); 530 _asyncCompleteWithErrorCallback(doneSignal, error, stackTrace);
499 return; 531 return;
500 } 532 }
501 if (result is Future<bool>) { 533 if (result is Future<bool>) {
502 result.then(nextIteration, onError: doneSignal._completeError); 534 result.then(nextIteration, onError: doneSignal._completeError);
503 return; 535 return;
504 } 536 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 * in exactly the same way as for [then]'s `onError`. 612 * in exactly the same way as for [then]'s `onError`.
581 * 613 *
582 * If `test` is omitted, it defaults to a function that always returns true. 614 * If `test` is omitted, it defaults to a function that always returns true.
583 * The `test` function should not throw, but if it does, it is handled as 615 * The `test` function should not throw, but if it does, it is handled as
584 * if the `onError` function had thrown. 616 * if the `onError` function had thrown.
585 * 617 *
586 * Note that futures don't delay reporting of errors until listeners are 618 * Note that futures don't delay reporting of errors until listeners are
587 * added. If the first `catchError` (or `then`) call happens after this future 619 * added. If the first `catchError` (or `then`) call happens after this future
588 * has completed with an error then the error is reported as unhandled error. 620 * has completed with an error then the error is reported as unhandled error.
589 * See the description on [Future]. 621 * See the description on [Future].
590 *
591 * Example:
592 *
593 * foo
594 * .catchError(..., test: (e) => e is ArgumentError)
595 * .catchError(..., test: (e) => e is NoSuchMethodError)
596 * .then((v) { ... });
597 *
598 * This method is equivalent to:
599 *
600 * Future catchError(onError(error),
601 * {bool test(error)}) {
602 * this.then((v) => v, // Forward the value.
603 * // But handle errors, if the [test] succeeds.
604 * onError: (e, stackTrace) {
605 * if (test == null || test(e)) {
606 * if (onError is ZoneBinaryCallback) {
607 * return onError(e, stackTrace);
608 * }
609 * return onError(e);
610 * }
611 * throw e;
612 * });
613 * }
614 *
615 */ 622 */
616 // The `Function` below stands for one of two types: 623 // The `Function` below stands for one of two types:
617 // - (dynamic) -> FutureOr<T> 624 // - (dynamic) -> FutureOr<T>
618 // - (dynamic, StackTrace) -> FutureOr<T> 625 // - (dynamic, StackTrace) -> FutureOr<T>
619 // Given that there is a `test` function that is usually used to do an 626 // Given that there is a `test` function that is usually used to do an
620 // `isCheck` we should also expect functions that take a specific argument. 627 // `isCheck` we should also expect functions that take a specific argument.
621 // Note: making `catchError` return a `Future<T>` in non-strong mode could be 628 // Note: making `catchError` return a `Future<T>` in non-strong mode could be
622 // a breaking change. 629 // a breaking change.
623 Future<T> catchError(Function onError, {bool test(Object error)}); 630 Future<T> catchError(Function onError, {bool test(Object error)});
624 631
625 /** 632 /**
626 * Register a function to be called when this future completes. 633 * Registers a function to be called when this future completes.
627 * 634 *
628 * The [action] function is called when this future completes, whether it 635 * The [action] function is called when this future completes, whether it
629 * does so with a value or with an error. 636 * does so with a value or with an error.
630 * 637 *
631 * This is the asynchronous equivalent of a "finally" block. 638 * This is the asynchronous equivalent of a "finally" block.
632 * 639 *
633 * The future returned by this call, `f`, will complete the same way 640 * The future returned by this call, `f`, will complete the same way
634 * as this future unless an error occurs in the [action] call, or in 641 * as this future unless an error occurs in the [action] call, or in
635 * a [Future] returned by the [action] call. If the call to [action] 642 * a [Future] returned by the [action] call. If the call to [action]
636 * does not return a future, its return value is ignored. 643 * does not return a future, its return value is ignored.
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 713 }
707 } 714 }
708 715
709 /** 716 /**
710 * A way to produce Future objects and to complete them later 717 * A way to produce Future objects and to complete them later
711 * with a value or error. 718 * with a value or error.
712 * 719 *
713 * Most of the time, the simplest way to create a future is to just use 720 * Most of the time, the simplest way to create a future is to just use
714 * one of the [Future] constructors to capture the result of a single 721 * one of the [Future] constructors to capture the result of a single
715 * asynchronous computation: 722 * asynchronous computation:
716 * 723 * ```
717 * new Future(() { doSomething(); return result; }); 724 * new Future(() { doSomething(); return result; });
718 * 725 * ```
719 * or, if the future represents the result of a sequence of asynchronous 726 * or, if the future represents the result of a sequence of asynchronous
720 * computations, they can be chained using [Future.then] or similar functions 727 * computations, they can be chained using [Future.then] or similar functions
721 * on [Future]: 728 * on [Future]:
722 * 729 * ```
723 * Future doStuff(){ 730 * Future doStuff(){
724 * return someAsyncOperation().then((result) { 731 * return someAsyncOperation().then((result) {
725 * return someOtherAsyncOperation(result); 732 * return someOtherAsyncOperation(result);
726 * }); 733 * });
727 * } 734 * }
728 * 735 * ```
729 * If you do need to create a Future from scratch — for example, 736 * If you do need to create a Future from scratch — for example,
730 * when you're converting a callback-based API into a Future-based 737 * when you're converting a callback-based API into a Future-based
731 * one — you can use a Completer as follows: 738 * one — you can use a Completer as follows:
739 * ```
740 * class AsyncOperation {
741 * Completer _completer = new Completer();
732 * 742 *
733 * class AsyncOperation { 743 * Future<T> doOperation() {
734 * Completer _completer = new Completer(); 744 * _startOperation();
745 * return _completer.future; // Send future object back to client.
746 * }
735 * 747 *
736 * Future<T> doOperation() { 748 * // Something calls this when the value is ready.
737 * _startOperation(); 749 * void _finishOperation(T result) {
738 * return _completer.future; // Send future object back to client. 750 * _completer.complete(result);
739 * } 751 * }
740 * 752 *
741 * // Something calls this when the value is ready. 753 * // If something goes wrong, call this.
742 * void _finishOperation(T result) { 754 * void _errorHappened(error) {
743 * _completer.complete(result); 755 * _completer.completeError(error);
744 * } 756 * }
745 * 757 * }
746 * // If something goes wrong, call this. 758 * ```
747 * void _errorHappened(error) {
748 * _completer.completeError(error);
749 * }
750 * }
751 */ 759 */
752 abstract class Completer<T> { 760 abstract class Completer<T> {
753 /** 761 /**
754 * Creates a new completer. 762 * Creates a new completer.
755 * 763 *
756 * The general workflow for creating a new future is to 1) create a 764 * The general workflow for creating a new future is to 1) create a
757 * new completer, 2) hand out its future, and, at a later point, 3) invoke 765 * new completer, 2) hand out its future, and, at a later point, 3) invoke
758 * either [complete] or [completeError]. 766 * either [complete] or [completeError].
759 * 767 *
760 * The completer completes the future asynchronously. That means that 768 * The completer completes the future asynchronously. That means that
761 * callbacks registered on the future, are not called immediately when 769 * callbacks registered on the future are not called immediately when
762 * [complete] or [completeError] is called. Instead the callbacks are 770 * [complete] or [completeError] is called. Instead the callbacks are
763 * delayed until a later microtask. 771 * delayed until a later microtask.
764 * 772 *
765 * Example: 773 * Example:
766 * 774 * ```
767 * var completer = new Completer(); 775 * var completer = new Completer();
768 * handOut(completer.future); 776 * handOut(completer.future);
769 * later: { 777 * later: {
770 * completer.complete('completion value'); 778 * completer.complete('completion value');
771 * } 779 * }
780 * ```
772 */ 781 */
773 factory Completer() => new _AsyncCompleter<T>(); 782 factory Completer() => new _AsyncCompleter<T>();
774 783
775 /** 784 /**
776 * Completes the future synchronously. 785 * Completes the future synchronously.
777 * 786 *
778 * This constructor should be avoided unless the completion of the future is 787 * This constructor should be avoided unless the completion of the future is
779 * known to be the final result of another asynchronous operation. If in doubt 788 * known to be the final result of another asynchronous operation. If in doubt
780 * use the default [Completer] constructor. 789 * use the default [Completer] constructor.
781 * 790 *
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 * // The completion is the result of the asynchronous onDone event. 826 * // The completion is the result of the asynchronous onDone event.
818 * // However, there is still code executed after the completion. This 827 * // However, there is still code executed after the completion. This
819 * // operation is *not* safe. 828 * // operation is *not* safe.
820 * stream.listen(print, onDone: () { 829 * stream.listen(print, onDone: () {
821 * completer.complete("done"); 830 * completer.complete("done");
822 * foo(); // In this case, foo() runs after bar(). 831 * foo(); // In this case, foo() runs after bar().
823 * }); 832 * });
824 */ 833 */
825 factory Completer.sync() => new _SyncCompleter<T>(); 834 factory Completer.sync() => new _SyncCompleter<T>();
826 835
827 /** The future that will contain the result provided to this completer. */ 836 /**
837 * The future that is completed by this completer.
838 *
839 * The future that is completed when [complete] or [completeError] is called.
840 */
828 Future<T> get future; 841 Future<T> get future;
829 842
830 /** 843 /**
831 * Completes [future] with the supplied values. 844 * Completes [future] with the supplied values.
832 * 845 *
833 * The value must be either a value of type [T] 846 * The value must be either a value of type [T]
834 * or a future of type `Future<T>`. 847 * or a future of type `Future<T>`.
835 * 848 *
836 * If the value is itself a future, the completer will wait for that future 849 * If the value is itself a future, the completer will wait for that future
837 * to complete, and complete with the same result, whether it is a success 850 * to complete, and complete with the same result, whether it is a success
838 * or an error. 851 * or an error.
839 * 852 *
840 * Calling `complete` or [completeError] must not be done more than once. 853 * Calling [complete] or [completeError] must be done at most once.
841 * 854 *
842 * All listeners on the future are informed about the value. 855 * All listeners on the future are informed about the value.
843 */ 856 */
844 void complete([FutureOr<T> value]); 857 void complete([FutureOr<T> value]);
845 858
846 /** 859 /**
847 * Complete [future] with an error. 860 * Complete [future] with an error.
848 * 861 *
849 * Calling [complete] or `completeError` must not be done more than once. 862 * Calling [complete] or [completeError] must be done at most once.
850 * 863 *
851 * Completing a future with an error indicates that an exception was thrown 864 * Completing a future with an error indicates that an exception was thrown
852 * while trying to produce a value. 865 * while trying to produce a value.
853 * 866 *
854 * If [error] is `null`, it is replaced by a [NullThrownError]. 867 * If [error] is `null`, it is replaced by a [NullThrownError].
855 * 868 *
856 * If `error` is a `Future`, the future itself is used as the error value. 869 * If `error` is a `Future`, the future itself is used as the error value.
857 * If you want to complete with the result of the future, you can use: 870 * If you want to complete with the result of the future, you can use:
858 * 871 * ```
859 * thisCompleter.complete(theFuture) 872 * thisCompleter.complete(theFuture)
860 * 873 * ```
861 * or if you only want to handle an error from the future: 874 * or if you only want to handle an error from the future:
862 * 875 * ```
863 * theFuture.catchError(thisCompleter.completeError); 876 * theFuture.catchError(thisCompleter.completeError);
864 * 877 * ```
865 */ 878 */
866 void completeError(Object error, [StackTrace stackTrace]); 879 void completeError(Object error, [StackTrace stackTrace]);
867 880
868 /** 881 /**
869 * Whether the future has been completed. 882 * Whether the [future] has been completed.
883 *
884 * Reflects whether [complete] or [completeError] has been called.
885 * A `true` value doesn't necessarily mean that listeners of this future
886 * have been invoked yet, either because the completer usually waits until
887 * a later microtask to propagate the result, or because [complete]
888 * was called with a future that hasn't completed yet.
889 *
890 * When this value is `true`, [complete] and [completeError] must not be
891 * called again.
870 */ 892 */
871 bool get isCompleted; 893 bool get isCompleted;
872 } 894 }
873 895
874 // Helper function completing a _Future with error, but checking the zone 896 // Helper function completing a _Future with error, but checking the zone
875 // for error replacement first. 897 // for error replacement first.
876 void _completeWithErrorCallback(_Future result, error, stackTrace) { 898 void _completeWithErrorCallback(_Future result, error, stackTrace) {
877 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); 899 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
878 if (replacement != null) { 900 if (replacement != null) {
879 error = _nonNullError(replacement.error); 901 error = _nonNullError(replacement.error);
880 stackTrace = replacement.stackTrace; 902 stackTrace = replacement.stackTrace;
881 } 903 }
882 result._completeError(error, stackTrace); 904 result._completeError(error, stackTrace);
883 } 905 }
884 906
885 // Like [_completeWIthErrorCallback] but completes asynchronously. 907 // Like [_completeWithErrorCallback] but completes asynchronously.
886 void _asyncCompleteWithErrorCallback(_Future result, error, stackTrace) { 908 void _asyncCompleteWithErrorCallback(_Future result, error, stackTrace) {
887 AsyncError replacement = Zone.current.errorCallback(error, stackTrace); 909 AsyncError replacement = Zone.current.errorCallback(error, stackTrace);
888 if (replacement != null) { 910 if (replacement != null) {
889 error = _nonNullError(replacement.error); 911 error = _nonNullError(replacement.error);
890 stackTrace = replacement.stackTrace; 912 stackTrace = replacement.stackTrace;
891 } 913 }
892 result._asyncCompleteError(error, stackTrace); 914 result._asyncCompleteError(error, stackTrace);
893 } 915 }
894 916
895 /** Helper function that converts `null` to a [NullThrownError]. */ 917 /** Helper function that converts `null` to a [NullThrownError]. */
896 Object _nonNullError(Object error) => error ?? new NullThrownError(); 918 Object _nonNullError(Object error) => error ?? new NullThrownError();
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/async/stream.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698