Index: sdk/lib/async/future.dart |
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart |
index 10aa237f9f08d0a8cca20e86d44fcf227ea69874..d2c120179f333c2fa4e332726e03b75a44a25631 100644 |
--- a/sdk/lib/async/future.dart |
+++ b/sdk/lib/async/future.dart |
@@ -233,20 +233,36 @@ abstract class Future<T> { |
return result; |
} |
+ /** Helper function that moves try/catch out of the main wait function. */ |
+ static void _safeCleanUp(var value, void cleanUp(value)) { |
+ try { |
+ cleanUp(value); |
+ } on Object { |
+ // Swallow any error. We are already reporting an earlier error. |
+ } |
+ } |
+ |
/** |
* Wait for all the given futures to complete and collect their values. |
* |
* Returns a future which will complete once all the futures in a list are |
* complete. If any of the futures in the list completes with an error, |
* the resulting future also completes with an error. Otherwise the value |
- * of the returned future will be a list of all the values that were produced. |
+ * of the returned future will be a list of all the values that were |
+ * produced. |
* |
* If `eagerError` is true, the future completes with an error immediately on |
* the first error from one of the futures. Otherwise all futures must |
* complete before the returned future is completed (still with the first |
* error to occur, the remaining errors are silently dropped). |
+ * |
+ * If [cleanUp] is provided, in the case of an error, any non-null result of |
kevmoo
2014/12/18 23:17:50
This could be a bit more clear.
...in case of an
Lasse Reichstein Nielsen
2014/12/19 06:54:11
Any futures completing successfully after the firs
|
+ * a successful future is passed to `cleanUp`, which can then release any |
+ * resources that the successful operation allocated. |
*/ |
- static Future<List> wait(Iterable<Future> futures, {bool eagerError: false}) { |
+ static Future<List> wait(Iterable<Future> futures, |
+ {bool eagerError: false, |
+ void cleanUp(successValue)}) { |
final _Future<List> result = new _Future<List>(); |
List values; // Collects the values. Set to null on error. |
int remaining = 0; // How many futures are we waiting for. |
@@ -254,11 +270,15 @@ abstract class Future<T> { |
StackTrace stackTrace; // The stackTrace that came with the error. |
// Handle an error from any of the futures. |
- handleError(theError, theStackTrace) { |
- final bool isFirstError = (values != null); |
- values = null; |
+ void handleError(theError, theStackTrace) { |
remaining--; |
- if (isFirstError) { |
+ if (values != null) { |
+ if (cleanUp != null) { |
+ for (var value in values) { |
+ if (value != null) _safeCleanUp(value, cleanUp); |
+ } |
+ } |
+ values = null; |
if (remaining == 0 || eagerError) { |
result._completeError(theError, theStackTrace); |
} else { |
@@ -281,8 +301,13 @@ abstract class Future<T> { |
if (remaining == 0) { |
result._completeWithValue(values); |
} |
- } else if (remaining == 0 && !eagerError) { |
- result._completeError(error, stackTrace); |
+ } else { |
+ if (cleanUp != null && value != null) { |
+ _safeCleanUp(value, cleanUp); |
+ } |
+ if (remaining == 0 && !eagerError) { |
+ result._completeError(error, stackTrace); |
+ } |
} |
}, onError: handleError); |
} |