| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 // Dart core library. | 5 // Dart core library. |
| 6 | 6 |
| 7 | 7 |
| 8 /** | 8 /** |
| 9 * A Future is used to obtain a value sometime in the | 9 * A [Future] is used to obtain a value sometime in the future. Receivers of a |
| 10 * future. | 10 * [Future] obtain the value by passing a callback to [then]. For example: |
| 11 * | |
| 12 * Receivers of a Future obtain the value by passing | |
| 13 * a callback to the 'then' method of Future. | |
| 14 * | |
| 15 * For example: | |
| 16 * | 11 * |
| 17 * Future<int> future = getFutureFromSomewhere(); | 12 * Future<int> future = getFutureFromSomewhere(); |
| 18 * future.then((value) { | 13 * future.then((value) { |
| 19 * print("I received the number " + value); | 14 * print("I received the number " + value); |
| 20 * }); | 15 * }); |
| 21 * | |
| 22 */ | 16 */ |
| 23 interface Future<T> default FutureImpl<T> { | 17 interface Future<T> default FutureImpl<T> { |
| 18 |
| 24 /** A future whose value is immediately available. */ | 19 /** A future whose value is immediately available. */ |
| 25 Future.immediate(T value); | 20 Future.immediate(T value); |
| 26 | 21 |
| 27 /** | 22 /** The value provided. Throws an exception if [hasValue] is false. */ |
| 28 * The value this future provided. (If called when hasValue | |
| 29 * is false, then throws an exception.) | |
| 30 */ | |
| 31 T get value(); | 23 T get value(); |
| 32 | 24 |
| 33 /** | 25 /** |
| 34 * Exception that occurred (null if no exception occured). (If called | 26 * Exception that occurred ([:null:] if no exception occured). This property |
| 35 * before [isComplete] is true, then this exception property itself | 27 * throws a [FutureNotCompleteException] if it is used before this future is |
| 36 * throws a FutureNotCompleteException.) | 28 * completes. |
| 37 */ | 29 */ |
| 38 Object get exception(); | 30 Object get exception(); |
| 39 | 31 |
| 40 /** | 32 /** |
| 41 * Whether the future is complete (either the value is available or there | 33 * Whether the future is complete (either the value is available or there was |
| 42 * was an exception). | 34 * an exception). |
| 43 */ | 35 */ |
| 44 bool get isComplete(); | 36 bool get isComplete(); |
| 45 | 37 |
| 46 /** | 38 /** |
| 47 * Whether the value is available (meaning isComplete is true, and there | 39 * Whether the value is available (meaning [isComplete] is true, and there was |
| 48 * was no exception). | 40 * no exception). |
| 49 */ | 41 */ |
| 50 bool get hasValue(); | 42 bool get hasValue(); |
| 51 | 43 |
| 52 /** | 44 /** |
| 53 * When this future is complete and has a value, then call | 45 * When this future is complete and has a value, then [onComplete] is called |
| 54 * the onComplete callback function with the value. | 46 * with the value. |
| 55 */ | 47 */ |
| 56 void then(void onComplete(T value)); | 48 void then(void onComplete(T value)); |
| 57 | 49 |
| 58 /** | 50 /** |
| 59 * If this future gets an exception, then call onException. | 51 * If this future gets an exception, then call [onException]. |
| 60 * | 52 * |
| 61 * If onException returns true, then the exception is considered | 53 * If [onException] returns true, then the exception is considered handled. |
| 62 * handled. | |
| 63 * | 54 * |
| 64 * If onException does not return true (or handleException was never called), | 55 * If [onException] does not return true (or [handleException] was never |
| 65 * then the exception is not considered handled. In that case, if there were | 56 * called), then the exception is not considered handled. In that case, if |
| 66 * any calls to [then] (meaning that there are onComplete callbacks waiting | 57 * there were any calls to [then], then the exception will be thrown when the |
| 67 * for the value), then the exception will be thrown when it is set. | 58 * value is set. |
| 68 * | 59 * |
| 69 * (In most cases it should not be necessary to call handleException, | 60 * In most cases it should not be necessary to call [handleException], |
| 70 * because the exception associated with this Future will propagate naturally | 61 * because the exception associated with this [Future] will propagate |
| 71 * if the future's value is being consumed. Only call handleException if you | 62 * naturally if the future's value is being consumed. Only call |
| 72 * need to do some special local exception handling related to this | 63 * [handleException] if you need to do some special local exception handling |
| 73 * particular Future's value.) | 64 * related to this particular Future's value. |
| 74 */ | 65 */ |
| 75 void handleException(bool onException(Object exception)); | 66 void handleException(bool onException(Object exception)); |
| 76 | 67 |
| 77 /** | 68 /** |
| 78 * A future representing [transformation] applied to this future's value. | 69 * A future representing [transformation] applied to this future's value. |
| 79 * | 70 * |
| 80 * When this future gets a value, [transformation] will be called on the | 71 * When this future gets a value, [transformation] will be called on the |
| 81 * value, and the returned future will receive the result. | 72 * value, and the returned future will receive the result. |
| 82 * | 73 * |
| 83 * If an exception occurs (received by this future, or thrown by | 74 * If an exception occurs (received by this future, or thrown by |
| 84 * [transformation]) then the returned future will receive the exception. | 75 * [transformation]) then the returned future will receive the exception. |
| 85 * | 76 * |
| 86 * You must not add exception handlers to [this] future prior to calling | 77 * You must not add exception handlers to [this] future prior to calling |
| 87 * transform, and any you add afterwards will not be invoked. | 78 * transform, and any you add afterwards will not be invoked. |
| 88 */ | 79 */ |
| 89 Future transform(Function transformation); | 80 Future transform(transformation(T value)); |
| 90 | 81 |
| 91 /** | 82 /** |
| 92 * A future representing an asynchronous transformation applied to this | 83 * A future representing an asynchronous transformation applied to this |
| 93 * future's value. [transformation] must return a Future. | 84 * future's value. [transformation] must return a Future. |
| 94 * | 85 * |
| 95 * When this future gets a value, [transformation] will be called on the | 86 * When this future gets a value, [transformation] will be called on the |
| 96 * value. When the resulting future gets a value, the returned future | 87 * value. When the resulting future gets a value, the returned future |
| 97 * will receive it. | 88 * will receive it. |
| 98 * | 89 * |
| 99 * If an exception occurs (received by this future, thrown by | 90 * If an exception occurs (received by this future, thrown by |
| 100 * [transformation], or received by the future returned by [transformation]) | 91 * [transformation], or received by the future returned by [transformation]) |
| 101 * then the returned future will receive the exception. | 92 * then the returned future will receive the exception. |
| 102 * | 93 * |
| 103 * You must not add exception handlers to [this] future prior to calling | 94 * You must not add exception handlers to [this] future prior to calling |
| 104 * chain, and any you add afterwards will not be invoked. | 95 * chain, and any you add afterwards will not be invoked. |
| 105 */ | 96 */ |
| 106 Future chain(Function transformation); | 97 Future chain(Future transformation(T value)); |
| 107 } | 98 } |
| 108 | 99 |
| 109 | 100 |
| 110 /** | 101 /** |
| 111 * A Completer is used to produce Future objects, and supply | 102 * A [Completer] is used to produce [Future]s and supply their value when it |
| 112 * a value to the Future object when the value becomes available. | 103 * becomes available. |
| 113 * | 104 * |
| 114 * A service that provides values to callers, and wants to return Future objects | 105 * A service that provides values to callers, and wants to return [Future]s can |
| 115 * rather than returning the values immediately, can use a Completer as follows: | 106 * use a [Completer] as follows: |
| 116 * | 107 * |
| 117 * Completer completer = new Completer(); | 108 * Completer completer = new Completer(); |
| 118 * Future future = completer.future; | 109 * // send future object back to client... |
| 119 * | 110 * return completer.future; |
| 120 * // send [future] object back to client... | 111 * ... |
| 121 * | 112 * |
| 122 * // later when value is available, call: | 113 * // later when value is available, call: |
| 123 * completer.complete(value); | 114 * completer.complete(value); |
| 124 * | 115 * |
| 125 * // alternatively, if the service cannot produce the value, it | 116 * // alternatively, if the service cannot produce the value, it |
| 126 * // can provide an exception: | 117 * // can provide an exception: |
| 127 * completer.completeException(exception); | 118 * completer.completeException(exception); |
| 128 * | 119 * |
| 129 */ | 120 */ |
| 130 interface Completer<T> default CompleterImpl<T> { | 121 interface Completer<T> default CompleterImpl<T> { |
| 131 | 122 |
| 132 /** Create a completer */ | |
| 133 Completer(); | 123 Completer(); |
| 134 | 124 |
| 125 /** The future that will contain the value produced by this completer. */ |
| 135 Future get future(); | 126 Future get future(); |
| 136 | 127 |
| 137 /** | 128 /** Supply a value for [future]. */ |
| 138 * Called when value is available. | |
| 139 */ | |
| 140 void complete(T value); | 129 void complete(T value); |
| 141 | 130 |
| 142 /** | 131 /** |
| 143 * Called if an exception occured while trying to produce value. | 132 * Indicate in [future] that an exception occured while trying to produce its |
| 133 * value. The argument [exception] argument should not be [:null:]. |
| 144 */ | 134 */ |
| 145 void completeException(Object exception); | 135 void completeException(Object exception); |
| 146 } | 136 } |
| 147 | 137 |
| 138 /** Thrown when reading a future's properties before it is complete. */ |
| 139 class FutureNotCompleteException implements Exception { |
| 140 FutureNotCompleteException() {} |
| 141 String toString() => "Exception: future has not been completed"; |
| 142 } |
| 148 | 143 |
| 149 /** | 144 /** |
| 150 * This class is for utility functions that operate on Futures (for | 145 * Thrown if a completer tries to set the value on a future that is already |
| 151 * example, waiting for a collectin of Futures to complete). | 146 * complete. |
| 147 */ |
| 148 class FutureAlreadyCompleteException implements Exception { |
| 149 FutureAlreadyCompleteException() {} |
| 150 String toString() => "Exception: future already completed"; |
| 151 } |
| 152 |
| 153 |
| 154 /** |
| 155 * [Futures] holds additional utility functions that operate on [Future]s (for |
| 156 * example, waiting for a collection of Futures to complete). |
| 152 */ | 157 */ |
| 153 class Futures { | 158 class Futures { |
| 154 | 159 |
| 155 /** | 160 /** |
| 156 * Returns a future which will complete once all the futures in a | 161 * Returns a future which will complete once all the futures in a list are |
| 157 * list are complete. (The value of the returned future will | 162 * complete. (The value of the returned future will be a list of all the |
| 158 * be a list of all the values that were produced.) | 163 * values that were produced.) |
| 159 */ | 164 */ |
| 160 static Future<List> wait(List<Future> futures) { | 165 static Future<List> wait(List<Future> futures) { |
| 161 Completer completer = new Completer<List>(); | 166 Completer completer = new Completer<List>(); |
| 162 int remaining = futures.length; | 167 int remaining = futures.length; |
| 163 List<Object> values = new List(futures.length); | 168 List<Object> values = new List(futures.length); |
| 164 | 169 |
| 165 // As each future completes, put its value into the corresponding | 170 // As each future completes, put its value into the corresponding |
| 166 // position in the list of values. | 171 // position in the list of values. |
| 167 for (int i = 0; i < futures.length; i++) { | 172 for (int i = 0; i < futures.length; i++) { |
| 168 // TODO(mattsh) - remove this after bug | 173 // TODO(mattsh) - remove this after bug |
| 169 // http://code.google.com/p/dart/issues/detail?id=333 is fixed. | 174 // http://code.google.com/p/dart/issues/detail?id=333 is fixed. |
| 170 int pos = i; | 175 int pos = i; |
| 171 futures[pos].then((Object value) { | 176 futures[pos].then((Object value) { |
| 172 values[pos] = value; | 177 values[pos] = value; |
| 173 if (--remaining == 0) { | 178 if (--remaining == 0) { |
| 174 completer.complete(values); | 179 completer.complete(values); |
| 175 } | 180 } |
| 176 }); | 181 }); |
| 177 } | 182 } |
| 183 |
| 178 // Special case where all the futures are already completed, | 184 // Special case where all the futures are already completed, |
| 179 // trigger the value now. | 185 // trigger the value now. |
| 180 if (futures.length == 0) { | 186 if (futures.length == 0) { |
| 181 completer.complete(values); | 187 completer.complete(values); |
| 182 } | 188 } |
| 183 | 189 |
| 184 return completer.future; | 190 return completer.future; |
| 185 } | 191 } |
| 186 } | 192 } |
| 187 | |
| OLD | NEW |