首页 > 解决方案 > 如果在 Flutter 中失败,Future 可以在内部重试 http 请求吗?

问题描述

我正在使用以下代码成功轮询 mysite 以获取 JSON 数据并返回该数据。如果请求失败,那么它也会成功返回错误消息return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0);

我想要发生的是让应用程序在返回错误消息之前重试请求 3 次。

基本上让未来调用自己进行一些迭代。

我确实尝试创建一个外部函数,该函数将从外部 catch 调用,然后依次调用 getJSONfromTheSite 函数第二次和第三次,但问题是您将从 Future 获得非空返回,所以该应用程序不会接受这种方法

还有另一种方法吗?

          Future<Result> getJSONfromTheSite(String call) async {
            debugPrint('Network Attempt by getJSONfromTheSite');
            try {

              final response = await http.get(Uri.parse('http://www.thesite.com/'));

              if (response.statusCode == 200) {
                return Result<AppData>.success(AppData.fromRawJson(response.body));
              } else {
                //return Result.error("Error","Status code not 200", 1);
                return Result.error(title:"Error",msg:"Status code not 200", errorcode:1);
              }
            } catch (error) {
                return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0);
            }
          }

标签: flutterdart

解决方案


下面的扩展方法会为futures创建一个工厂,创建它们并尝试它们,直到达到重试限制:

extension Retry<T> on Future<T> Function() {
  Future<T> withRetries(int count) async {
    while(true) {
      try {
        final future = this();
        return await future;
      } 
      catch (e) {
        if(count > 0) {
          count--;
        }
        else {
          rethrow;
        }
      }
    }
  }
}

假设你有一个相当简单的飞镖方法:

 Future<AppData> getJSONfromTheSite(String call) async {
      final response = await http.get(Uri.parse('http://www.thesite.com/'));

      if (response.statusCode == 200) {
        return AppData.fromRawJson(response.body);
      } else {
        throw Exception('Error');
      }
  }

你现在可以这样称呼它:

try {
  final result = (() => getJSONfromTheSite('call data')).withRetries(3);
  // succeeded at some point, "result" being the successful result
}
catch (e) {
  // failed 3 times, the last error is in "e"
}

如果您没有成功或抛出异常的普通方法,则必须调整重试方法以了解何时出现错误。也许使用具有Either类型的更多功能包之一,以便您可以确定返回值是否是错误。


推荐阅读