如何在Dart/Flutter中重试Future?

5

我有一个进行异步处理的方法,并希望它重试X次。在Dart/Flutter中如何实现?

4个回答

13

使用此函数:

typedef Future<T> FutureGenerator<T>();
Future<T> retry<T>(int retries, FutureGenerator aFuture) async {
  try {
    return await aFuture();
  } catch (e) {
    if (retries > 1) {
      return retry(retries - 1, aFuture);
    }

    rethrow;
  }
}

使用方法:

main(List<String> arguments) {

  retry(2, doSometing);

}

Future doSometing() async {
  print("Doing something...");
  await Future.delayed(Duration(milliseconds: 500));
  return "Something";
}

这段代码可能导致堆栈溢出。我建议使用while循环和bool检查。 - Michel Feinstein

7

6

我在Daniel Oliveira的答案中增加了一个可选的延迟:

typedef Future<T> FutureGenerator<T>();
Future<T> retry<T>(int retries, FutureGenerator aFuture, {Duration delay}) async {
  try {
    return await aFuture();
  } catch (e) {
    if (retries > 1) {
      if (delay != null) {
        await Future.delayed(delay);
      }
      return retry(retries - 1, aFuture);
    }
    rethrow;
  }
}

您可以如下使用它:
retry(2, doSometing, delay: const Duration(seconds: 1));

1
这是我的实现方式:
Future retry<T>(
    {Future<T> Function() function,
    int numberOfRetries = 3,
    Duration delayToRetry = const Duration(milliseconds: 500),
    String message = ''}) async {
  int retry = numberOfRetries;
  List<Exception> exceptions = [];

  while (retry-- > 0) {
    try {
      return await function();
    } catch (e) {
      exceptions.add(e);
    }
    if (message != null) print('$message:  retry - ${numberOfRetries - retry}');
    await Future.delayed(delayToRetry);
  }

  AggregatedException exception = AggregatedException(message, exceptions);
  throw exception;
}

class AggregatedException implements Exception {
  final String message;
  AggregatedException(this.message, this.exceptions)
      : lastException = exceptions.last,
        numberOfExceptions = exceptions.length;

  final List<Exception> exceptions;
  final Exception lastException;
  final int numberOfExceptions;

  String toString() {
    String result = '';
    exceptions.forEach((e) => result += e.toString() + '\\');
    return result;
  }
}

这是我使用它的方式:
  try {
      await retry(
          function: () async {
            _connection = await BluetoothConnection.toAddress(device.address);
          },
          message: 'Bluetooth Connect');
    } catch (e) {
      _log.finest('Bluetooth init failed  ${e.toString()}');
    }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接