dart - Flutter:Do an operation if await takes more then 2 seconds - Stack Overflow

admin2025-04-15  2

final response = await _errorReportRepository.sendErrorReport(event.errorReport);

Hi,I want to do an operation if this await takes more than 2 seconds and not stop the process.

Like an example. If it takes more than 2 seconds, change a variable to true directly after 2 seconds.

final response = await _errorReportRepository.sendErrorReport(event.errorReport);

Hi,I want to do an operation if this await takes more than 2 seconds and not stop the process.

Like an example. If it takes more than 2 seconds, change a variable to true directly after 2 seconds.

Share Improve this question edited Feb 4 at 14:25 Rami Dhouib asked Feb 4 at 14:14 Rami DhouibRami Dhouib 331 silver badge6 bronze badges 2
  • 1 maybe you are looking for Promise.race – derpirscher Commented Feb 4 at 14:17
  • 1 Thanks for response , but this is not javascript ,its flutter. – Rami Dhouib Commented Feb 4 at 14:25
Add a comment  | 

2 Answers 2

Reset to default 2
Future<void> handleErrorReport() async {
  bool isTimeout = false;
  Timer? timeoutTimer;

  // Start a timer to change the variable after 2 seconds
  timeoutTimer = Timer(Duration(seconds: 2), () {
    isTimeout = true;
    print('Timeout reached, isTimeout set to true');
  });

  try {
    await _errorReportRepository.sendErrorReport(event.errorReport);
    
    // If sendErrorReport completes first, cancel the timer
    timeoutTimer.cancel();
    print('Error report sent successfully.');
  } catch (e) {
    print('Error occurred: $e');
  }
}

This will set the variable timeout to true if the error report fututre takes more than 2 seconds but will cancel the timeout if the error future resolves before 2 seconds.

Another option would be to use Future.any, this will race the two futures, if the error report resolves before 2 seconds the timeout will be ignored, else the timeout future will resolve.

The selected answer is one way to do this manually (though it has its issues), but there is a more concise way using Future.timeout:

try {
  final response = await _errorReportRepository
    .sendErrorReport(event.errorReport)
    .timeout(const Duration(seconds: 2));
} on TimeoutException catch (e) {
  // Do something in response to the timeout
}

For completionist's sake, here's a manual version that doesn't have the await issue of the other answer:

import 'dart:async';

Future<T> timeout<T>(
  Future<T> future, {
  required Duration duration,
  FutureOr<T> Function()? onTimeout,
}) {
  final completer = Completer<T>();

  final timer = Timer(duration, () async {
    if (!completer.isCompleted) {
      if (onTimeout == null) {
        completer.completeError(TimeoutException('The future has timed out.'));
      } else {
        final value = await onTimeout();
        completer.complete(value);
      }
    }
  });

  future.then((value) {
    if (timer.isActive) {
      timer.cancel();
      completer.complete(value);
    }
  });

  return completer.future;
}

Usage:

Future<int> asyncTask() async {
  await Future.delayed(Duration(seconds: 3));
  return 5;
}

void main() async {
  print(await timeout(
    asyncTask(),
    duration: Duration(seconds: 4),
  ));
  // Prints '5' after 3 seconds
  
  print(await timeout(
    asyncTask(),
    duration: Duration(seconds: 2),
    onTimeout: () => -5,
  ));
  // Prints '-5' after 2 seconds
  
  try {
    print(await timeout(
      asyncTask(),
      duration: Duration(milliseconds: 500),
    ));
  } catch (e) {
    print(e);
  }

  // Prints 'TimeoutException: The future has timed out.' after half a second
}
转载请注明原文地址:http://anycun.com/QandA/1744714165a86600.html