Flutter Package: retry

发布时间 2023-05-25 14:32:01作者: R1cardo

Flutter package: retry

传送门

This package provides an easy way to retry asynchronous functions. This is often useful to avoid crashing on intermittent errors such as broken connections or temporarily overloaded servers.

这个包提供了一种重试异步函数的简单方法。这通常有助于避免因连接中断或服务器暂时过载等间歇性错误而崩溃。

其实就是当有异常抛出时重试

Google官方的库,但是主页又加了一句

Disclaimer: This is not an officially supported Google product.

免责声明:这不是官方支持的 Google 产品

......

直接使用

simple example:

final response = await retry(
  // Make a GET request
  () => http.get('https://google.com').timeout(Duration(seconds: 5)),
  // Retry on SocketException or TimeoutException
  retryIf: (e) => e is SocketException || e is TimeoutException,
);

访问https://google.com,如果报错且此错误为SocketException或者TimeoutException,则重试

一些主要参数

参数 描述
位置参数 需要调用的异步函数
retryIf 如果满足回调条件则重试,不传则只要是Exception就重试
maxAttempts 最大尝试次数
delayFactor 每次重试的延迟时间
randomizationFactor 每次重试的延迟随机浮动百分比

Using RetryOptions

    RetryOptions options = RetryOptions(
        delayFactor: const Duration(milliseconds: 400),
        randomizationFactor: 0.25,
        maxAttempts: 4,
        maxDelay: Duration(seconds: 20));

    options.retry(
      () async {
        // Make a HTTP request and return the status code.
        final HttpClientRequest request = await client
            .getUrl(Uri.parse('https://www.google.cn'))
            .timeout(const Duration(seconds: 5));
        final HttpClientResponse response =
            await request.close().timeout(const Duration(seconds: 5));
        await response.drain();
        return response.statusCode;
      },
      retryIf: (Exception e) => e is SocketException || e is TimeoutException,
    );

也可以使用RetryOptions来配置参数

加上randomizationFactor每次重试的时间就会上下浮动,比如设置为0.25,maxAttempts设置为8

那么在第一次到第七次重试就会按照以下时间休眠

  • 400 ms +/- 25%
  • 800 ms +/- 25%
  • 1600 ms +/- 25%
  • 3200 ms +/- 25%
  • 6400 ms +/- 25%
  • 12800 ms +/- 25%
  • 25600 ms +/- 25%

完整示例:

Future<void> retryFunction() async {
    // Create an HttpClient.
    final HttpClient client = HttpClient();

    try {
      // Get statusCode by retrying a function
      final int statusCode = await retry(
          () async {
            // Make a HTTP request and return the status code.
            final HttpClientRequest request = await client
                .getUrl(Uri.parse('https://www.google.cn'))
                .timeout(const Duration(seconds: 5));
            final HttpClientResponse response =
                await request.close().timeout(const Duration(seconds: 5));
            await response.drain();
            return response.statusCode;
          },
          // Retry on SocketException or TimeoutException
          retryIf: (Exception e) =>
              e is SocketException || e is TimeoutException,
          maxAttempts: 4,
          delayFactor: const Duration(seconds: 1),
          randomizationFactor: 0.5,
          onRetry: (Exception e) {
            log('onRetry');
          },
          maxDelay: const Duration(seconds: 20));

      // Print result from status code
      if (statusCode == 200) {
        if (kDebugMode) {
          print('google.com is running');
        }
      } else {
        if (kDebugMode) {
          print('google.com is not availble...');
        }
      }
    } finally {
      // Always close an HttpClient from dart:io, to close TCP connections in the
      // connection pool. Many servers has keep-alive to reduce round-trip time
      // for additional requests and avoid that clients run out of port and
      // end up in WAIT_TIME unpleasantries...
      client.close();
    }
  }