waitF<R> function

FutureOr<R> waitF<R>(
  1. Iterable<_TFactory> itemFactories,
  2. _TSyncOrAsyncMapper<Iterable, R> callback, {
  3. _TOnErrorCallback? onError,
  4. bool eagerError = true,
})

Implementation

FutureOr<R> waitF<R>(
  Iterable<_TFactory<dynamic>> itemFactories,
  _TSyncOrAsyncMapper<Iterable<dynamic>, R> callback, {
  _TOnErrorCallback? onError,
  bool eagerError = true,
}) {
  final buffer = <FutureOr<dynamic>>[];
  Object? firstSyncError;
  StackTrace? firstSyncStackTrace;
  var isFuture = false;
  for (final itemFactory in itemFactories) {
    try {
      if (eagerError && firstSyncError != null) {
        itemFactory();
        continue;
      }

      final item = itemFactory();
      buffer.add(item);
      if (item is Future) {
        isFuture = true;
      }
    } catch (e, s) {
      if (eagerError) {
        if (onError != null) {
          final errorResult = onError(e, s);
          if (errorResult is Future) {
            return errorResult.then((_) => _throwError(e, s));
          }
        }
        _throwError(e, s);
      }
      if (firstSyncError == null) {
        firstSyncError = e;
        firstSyncStackTrace = s;
        buffer.add(Future.error(e, s));
        isFuture = true;
      }
    }
  }
  if (!isFuture) {
    try {
      final result = callback(buffer);
      if (result is Future<R>) {
        return result.catchError((Object e, StackTrace? s) {
          if (onError != null) {
            return Future.sync(() => onError(e, s)).then((_) => throw e);
          }
          throw e;
        });
      }
      return result;
    } catch (e, s) {
      if (onError != null) {
        final errResult = onError(e, s);
        if (errResult is Future) return errResult.then((_) => throw e);
      }
      rethrow;
    }
  } else {
    return Future.wait(
          buffer.map((e) => Future.value(e)),
          eagerError: eagerError,
        )
        .then((items) {
          if (firstSyncError != null) {
            if (onError != null) {
              final errResult = onError(firstSyncError, firstSyncStackTrace);
              if (errResult is Future) {
                return errResult.then(
                  (_) => _throwError(firstSyncError!, firstSyncStackTrace),
                );
              }
            }
            _throwError(firstSyncError, firstSyncStackTrace);
          }
          return callback(items);
        })
        .catchError((Object e, StackTrace? s) {
          if (onError != null) {
            final errResult = onError(e, s);
            if (errResult is Future) {
              return errResult.then((_) => throw e);
            }
          }
          throw e;
        });
  }
}