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

Unified Diff: sdk/lib/async/future.dart

Issue 815773002: Add cleanUp function to Future.wait. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address comments. Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/async_helper/lib/async_helper.dart ('k') | tests/lib/async/future_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/async/future.dart
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 10aa237f9f08d0a8cca20e86d44fcf227ea69874..7f4050cf8cb6dc661af812fb51bb6f0267b9de57 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -239,14 +239,24 @@ abstract class Future<T> {
* 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
+ * a successful future is passed to `cleanUp`, which can then release any
+ * resources that the successful operation allocated.
+ *
+ * The call to `cleanUp` should not throw. If it does, the error will be an
+ * uncaught asynchronous error.
*/
- 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 +264,18 @@ 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) {
+ // Ensure errors from cleanUp are uncaught.
+ new Future.sync(() { cleanUp(value); });
+ }
+ }
+ }
+ values = null;
if (remaining == 0 || eagerError) {
result._completeError(theError, theStackTrace);
} else {
@@ -281,8 +298,14 @@ 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) {
+ // Ensure errors from cleanUp are uncaught.
+ new Future.sync(() { cleanUp(value); });
+ }
+ if (remaining == 0 && !eagerError) {
+ result._completeError(error, stackTrace);
+ }
}
}, onError: handleError);
}
« no previous file with comments | « pkg/async_helper/lib/async_helper.dart ('k') | tests/lib/async/future_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698