如果Flutter,Dart中没有响应,请重试Http Get请求

时间:2019-08-27 18:09:57

标签: flutter dart

getData() async {
    http.Response response = await http.get('https://www.example.com/);
    print(response.body);
}

上面的函数可以获取页面的HTML代码,但是在某些情况下会失败。该功能有时永远不会完成,并且会永远等待获取响应(例如,如果在关闭互联网的情况下打开该应用程序,即使打开了该应用程序,它也永远不会连接)。在这种情况下,有什么办法可以重试?

我尝试了http retry包,但它给了我15个以上的错误。

3 个答案:

答案 0 :(得分:1)

如何完成此操作的示例代码:

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<List> loadData() async {
  bool loadRemoteDatatSucceed = false;
  var data;
  try {
    http.Response response = await http.post("https://www.example.com",
        body: <String, String>{"username": "test"});
    data = json.decode(response.body);
    if (data.containsKey("success")) {
      loadRemoteDatatSucceed = true;
    }
  } catch (e) {
    if (loadRemoteDatatSucceed == false) retryFuture(loadData, 2000);
  }
  return data;
}

retryFuture(future, delay) {
  Future.delayed(Duration(milliseconds: delay), () {
    future();
  });
}

答案 1 :(得分:1)

您可以使用 http 包中的 RetryPolicy 重试您的连接,只需创建您自己的类并继承表单 RetryPolicy 并覆盖这些函数,如下例所示,然后使用 HttpClientWithInterceptor.build 创建一个 Client 并添加您的自定义 retryPolicy 作为参数,这将多次重试您的请求,直到满足条件,否则,它将停止重试。

import 'package:http/http.dart';

class MyRetryPolicy extends RetryPolicy {
  final url = 'https://www.example.com/';

  @override
  // how many times you want to retry your request.
  int maxRetryAttempts = 5;

  @override
  Future<bool> shouldAttemptRetryOnResponse(ResponseData response) async {
    //You can check if you got your response after certain timeout,
    //or if you want to retry your request based on the status code,
    //usually this is used for refreshing your expired token but you can check for what ever you want

    //your should write a condition here so it won't execute this code on every request
    //for example if(response == null) 

    // a very basic solution is that you can check
    // for internet connection, for example
    try {
      final result = await InternetAddress.lookup('google.com');
      if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
        return true;
      }
      return false;
    } on SocketException catch (_) {
      return false;
    }
  }
}
     

然后创建并使用客户端来提出您的请求。

如果满足你写的条件,它会自动重试请求。

Client client = HttpClientWithInterceptor.build(
        retryPolicy: ExpiredTokenRetryPolicy(),
      );

final response = await client.get('https://www.example.com/);

还有一个软件包可以检查互联网连接是否是您的问题,请参阅 connectivity

答案 2 :(得分:0)

您可以在异步函数中使用try-catch块,就像在同步代码中一样。也许您可以在函数中添加某种错误处理机制,然后在出错时重试该函数?这是其中一个documentation

文档示例:

  try {
    var order = await getUserOrder();
    print('Awaiting user order...');
  } catch (err) {
    print('Caught error: $err');
  }

您还可以按照this github issue.

捕获特定的异常
 doLogin(String username, String password) async {
    try {
     var user = await api.login(username, password);
      _view.onLoginSuccess(user);
    } on Exception catch(error) {
      _view.onLoginError(error.toString());
    }
  }

编辑:这可能也有帮助。

在使用此功能时,请here查找可以多次尝试异步操作的函数。