简体   繁体   English

如果在 Flutter 中失败,Future 可以在内部重试 http 请求吗?

[英]Can a Future internally retry an http request if it fails in Flutter?

I'm using the following code to successfully poll mysite for JSON data and return that data.我正在使用以下代码成功轮询 mysite 以获取 JSON 数据并返回该数据。 If the request fails, then it successfully returns an error message as well return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0);如果请求失败,则成功返回错误信息return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0); . .

What I'd like to happen is have the app retry the request 3 times before it returns the error message.我想要发生的是让应用程序在返回错误消息之前重试请求 3 次。

Basically have the future call itself for some number of iterations.基本上有一些迭代次数的未来调用本身。

I did try to create an external function that would get called from the outer catch which then would in turn call the getJSONfromTheSite function a second and then a third time, but the problem was that you would have a non-null return from the Future so the app wouldn't accept that approach我确实尝试创建一个外部函数,该函数将从外部 catch 调用,然后依次调用 getJSONfromTheSite 函数第二次和第三次,但问题是您将从 Future 获得非空返回,所以该应用程序不会接受这种方法

Is there another way of doing this?还有另一种方法吗?

          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);
            }
          }

The following extension method will take a factory for futures, create them and try them until the retry limit is reached:以下扩展方法将为期货创建一个工厂,创建它们并尝试它们,直到达到重试限制:

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;
        }
      }
    }
  }
}

Assuming you have a rather plain dart method:假设你有一个相当简单的飞镖方法:

 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');
      }
  }

You can now call it like this:你现在可以这样称呼它:

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"
}

If you don't have a plain method that either succeeds or throws an exception, you will have to adjust the retry method to know when something is an error.如果您没有成功或抛出异常的普通方法,则必须调整重试方法以了解何时出现错误。 Maybe use one of the more functional packages that have an Either type so you can figure out whether a return value is an error.也许使用有更多的功能包的一个Either类型,这样可以计算出一个返回值是否为错误。

Inside catch() you can count how many times have you retried, if counter is less than three you return the same getJSONfromTheSite() function, but with the summed counter.catch()您可以计算重试的次数,如果计数器小于 3,则返回相同的getJSONfromTheSite()函数,但使用总和计数器。 And if the connection keeps failing on try{} and the counter is greater than three it will then returns the error.如果连接在try{}上一直失败并且计数器大于 3,它将返回错误。

Future<Result> getJSONfromTheSite(String call, {counter = 0}) async {
            debugPrint('Network Attempt by getJSONfromTheSite');
            try {
              String? body = await tryGet();
              if (body != null) {
                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) {
                if(counter < 3) {  
                  counter += 1;
                  return getJSONfromTheSite(call, counter: counter);
                } else {
                  return Result.error(title:"No connection",msg:"Status code not 200", errorcode:0);
                }
            }
          }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 Dart/Flutter 中重试 Future? - How can I retry a Future in Dart/Flutter? Flutter, Dart 无响应时重试Http Get请求 - Retry Http Get request if there is no response in Flutter, Dart Flutter:json 数据未显示在未来构建器中的 http get 请求中 - Flutter: json data is not displaying in future builder on http get request Flutter | 物联网 | Http SoftAp 配置后请求失败 - Flutter | IoT | Http Request fails after SoftAp Provisioning 如果由于设备在 Flutter 中与 Internet 断开连接而导致请求未完成,我该如何重试 Dio 请求? - How can I retry a Dio request if the request doesn't complete because the device is disconnected from the Internet in Flutter? 当 flutter http 获取请求时返回 null 值(_ 的实例<future>动态的)</future> - returning null value when flutter http get request(Instances of _<Future> dynamic) 如何使用 Flutter Http 重试客户端刷新令牌? - How to refresh token with Flutter Http Retry Client? 捕获和处理 flutter 中的异常 未来 http 从不同的 class 调用的请求方法 - Catching and handling exception in flutter future http request method called from different class 如何在 graphql_flutter 中重试对 GraphQLError 的请求 - How to retry a request on GraphQLError in graphql_flutter flutter 问题与未来<http.response></http.response> - flutter problems w/ Future<http.Response>
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM