waitFor function

Future<void> waitFor(
  1. bool condition(), {
  2. Duration timeout = const Duration(seconds: 5),
  3. Duration interval = const Duration(milliseconds: 100),
})

Utility function to wait for a condition with a timeout.

Implementation

Future<void> waitFor(
  bool Function() condition, {
  Duration timeout = const Duration(seconds: 5),
  Duration interval = const Duration(milliseconds: 100),
}) async {
  ArgumentError.checkNotNull(condition, 'condition');
  ArgumentError.checkNotNull(timeout, 'timeout');
  ArgumentError.checkNotNull(interval, 'interval');

  if (timeout.isNegative) {
    throw ArgumentError.value(timeout, 'timeout', 'Cannot be negative');
  }

  if (interval.isNegative || interval == Duration.zero) {
    throw ArgumentError.value(interval, 'interval', 'Must be positive');
  }

  final stopwatch = Stopwatch()..start();
  Object? lastError;

  while (stopwatch.elapsed < timeout) {
    try {
      if (condition()) {
        return; // Condition met, exit successfully
      }
    } on Exception catch (error) {
      lastError = error;
      // Continue trying unless timeout is reached
    }

    await Future<void>.delayed(interval);
  }

  // Timeout reached
  final errorMessage = StringBuffer(
    'Condition was not met within ${timeout.inMilliseconds}ms',
  );
  if (lastError != null) {
    errorMessage.write('. Last error: $lastError');
  }

  throw TimeoutException(errorMessage.toString(), timeout);
}