Spec-Zone.ru › Dart 1

dart:async

wait метод

Future<List<T>> wait<T>(Iterable<Future<T>> futures, { bool eagerError: false, void cleanUp(T successValue) })

Ожидание завершения всех заданных будущих задач и сбор их значений.

Возвращает будущую задачу, которая завершится, когда все будущие задачи в списке завершатся.

Значение возвращаемой будущей задачи будет списком всех значений, которые были получены.

Если какая-либо из заданных будущих задач завершится с ошибкой, то возвращаемая будущая задача завершится с этой ошибкой. Если другие будущие задачи завершатся с ошибками, эти ошибки будут проигнорированы.

Если eagerError равно true, возвращаемая будущая задача завершится с ошибкой сразу после первой ошибки от одной из будущих задач. В противном случае все будущие задачи должны завершиться, прежде чем возвращаемая будущая задача завершится (все равно с первой ошибкой; оставшиеся ошибки будут проигнорированы).

В случае ошибки cleanUp (если предоставлена), вызывается для любого непустого результата успешных будущих задач. Это позволяет cleanUp ресурсы, которые в противном случае были бы потеряны (поскольку возвращаемая будущая задача не предоставляет доступ к этим значениям). Функция cleanup не используется, если ошибки нет.

Вызов cleanUp не должен вызывать исключения. Если это произойдет, ошибка станет необработанной асинхронной ошибкой.

Источник

static Future<List<T>> wait<T>(Iterable<Future<T>> futures,
    {bool eagerError: false, void cleanUp(T successValue)}) {
  final _Future<List<T>> result = new _Future<List<T>>();
  List<T> values; // Collects the values. Set to null on error.
  int remaining = 0; // How many futures are we waiting for.
  var error; // The first error from a future.
  StackTrace stackTrace; // The stackTrace that came with the error.

  // Handle an error from any of the futures.
  // TODO(jmesserly): use `void` return type once it can be inferred for the
  // `then` call below.
  handleError(theError, theStackTrace) {
    remaining--;
    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 {
        error = theError;
        stackTrace = theStackTrace;
      }
    } else if (remaining == 0 && !eagerError) {
      result._completeError(error, stackTrace);
    }
  }

  try {
    // As each future completes, put its value into the corresponding
    // position in the list of values.
    for (Future future in futures) {
      int pos = remaining;
      future.then((T value) {
        remaining--;
        if (values != null) {
          values[pos] = value;
          if (remaining == 0) {
            result._completeWithValue(values);
          }
        } 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);
      // Increment the 'remaining' after the call to 'then'.
      // If that call throws, we don't expect any future callback from
      // the future, and we also don't increment remaining.
      remaining++;
    }
    if (remaining == 0) {
      return new Future.value(const []);
    }
    values = new List<T>(remaining);
  } catch (e, st) {
    // The error must have been thrown while iterating over the futures
    // list, or while installing a callback handler on the future.
    if (remaining == 0 || eagerError) {
      // Throw a new Future.error.
      // Don't just call `result._completeError` since that would propagate
      // the error too eagerly, not giving the callers time to install
      // error handlers.
      // Also, don't use `_asyncCompleteError` since that one doesn't give
      // zones the chance to intercept the error.
      return new Future.error(e, st);
    } else {
      // Don't allocate a list for values, thus indicating that there was an
      // error.
      // Set error to the caught exception.
      error = e;
      stackTrace = st;
    }
  }
  return result;
}

© 2012 the Dart project authors
Licensed under the Creative Commons Attribution-ShareAlike License v4.0.
https://api.dartlang.org/stable/1.24.3/dart-async/Future/wait.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API