waitF<R> function

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

Waits for a list of FutureOr values and transforms the results.

Implementation

FutureOr<R> waitF<R>(
  Iterable<_TFactory<dynamic>> itemFactories,
  _TSyncOrAsyncMapper<Iterable<dynamic>, R> callback, {
  _TOnErrorCallback? onError,
  bool eagerError = true,
  _TOnCompleteCallback? onComplete,
}) {
  // Single in-order buffer: holds either raw sync values or pending Futures.
  // This guarantees the callback observes results in the same order the
  // caller passed them in — `consec2(asyncA, syncB, ...)` must see `[A, B]`,
  // not `[B, A]`. The previous implementation split sync/async into two
  // buffers and concatenated them, silently reordering arguments.
  final buffer = <dynamic>[];
  var hasAsync = false;
  _Error? syncError1;
  for (final itemFactory in itemFactories) {
    try {
      final item = itemFactory();
      buffer.add(item);
      if (item is Future) hasAsync = true;
    } catch (e, s) {
      if (eagerError) {
        return _handleErrorAndComplete(_Error(e, s), onError, onComplete);
      }
      // Record only the first sync error for reporting, but always push a
      // placeholder Future.error into the buffer so its length stays aligned
      // with the input. Otherwise `consecN`'s positional access drifts when
      // multiple sync factories throw under `eagerError: false`.
      syncError1 ??= _Error(e, s);
      buffer.add(Future<dynamic>.error(e, s));
      hasAsync = true;
    }
  }
  if (!hasAsync) {
    return _handleSyncPath(
      syncError1,
      buffer,
      callback,
      onError,
      onComplete,
    );
  }
  final asyncBuffer = buffer
      .map<Future<dynamic>>((e) => e is Future ? e : Future<dynamic>.value(e))
      .toList(growable: false);
  return _handleAsyncPath(
    syncError1,
    asyncBuffer,
    eagerError,
    callback,
    onError,
    onComplete,
  );
}