race<T> static method

CancelableOperation<T> race<T>(
  1. Iterable<CancelableOperation<T>> operations
)

Creates a CancelableOperation that completes with the value of the first of operations to complete.

Once any of operations completes, its result is forwarded to the new CancelableOperation and the rest are cancelled. If the bew operation is cancelled, all the operations are cancelled as well.

Implementation

static CancelableOperation<T> race<T>(
    Iterable<CancelableOperation<T>> operations) {
  operations = operations.toList();
  if (operations.isEmpty) {
    throw ArgumentError('May not be empty', 'operations');
  }

  var done = false;
  // Note: if one or more of the completers have already completed,
  // they're not actually cancelled by this.
  Future<void> cancelAll() {
    done = true;
    return Future.wait(operations.map((operation) => operation.cancel()));
  }

  var completer = CancelableCompleter<T>(onCancel: cancelAll);
  for (var operation in operations) {
    operation.then((value) {
      if (!done) cancelAll().whenComplete(() => completer.complete(value));
    }, onError: (error, stackTrace) {
      if (!done) {
        cancelAll()
            .whenComplete(() => completer.completeError(error, stackTrace));
      }
    });
  }

  return completer.operation;
}