Delinting future awaits round 2 (#10790)

* round 2

* deal with null futures

* review

* review

* review

* review
diff --git a/packages/flutter_tools/lib/src/base/process.dart b/packages/flutter_tools/lib/src/base/process.dart
index 0d51386..b3b4169 100644
--- a/packages/flutter_tools/lib/src/base/process.dart
+++ b/packages/flutter_tools/lib/src/base/process.dart
@@ -9,6 +9,7 @@
 import 'file_system.dart';
 import 'io.dart';
 import 'process_manager.dart';
+import 'utils.dart';
 
 typedef String StringConverter(String string);
 
@@ -156,12 +157,15 @@
 
   // Wait for stdout to be fully processed
   // because process.exitCode may complete first causing flaky tests.
-  await Future.wait(<Future<Null>>[
+  await waitGroup<Null>(<Future<Null>>[
     stdoutSubscription.asFuture<Null>(),
     stderrSubscription.asFuture<Null>(),
   ]);
-  stdoutSubscription.cancel();
-  stderrSubscription.cancel();
+
+  await waitGroup<Null>(<Future<Null>>[
+    stdoutSubscription.cancel(),
+    stderrSubscription.cancel(),
+  ]);
 
   return await process.exitCode;
 }
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index fddf40c..af7b8b8 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -256,3 +256,14 @@
     _timer = null;
   }
 }
+
+/// Returns a [Future] that completes when all given [Future]s complete.
+///
+/// Uses [Future.wait] but removes null elements from the provided
+/// `futures` iterable first.
+///
+/// The returned [Future<List>] will be shorter than the given `futures` if
+/// it contains nulls.
+Future<List<T>> waitGroup<T>(Iterable<Future<T>> futures) {
+  return Future.wait<T>(futures.where((Future<T> future) => future != null));
+}