getData() async {
http.Response response = await http.get('https://www.example.com/);
print(response.body);
}
上面的函数可以获取页面的HTML代码,但是在某些情况下会失败。该功能有时永远不会完成,并且会永远等待获取响应(例如,如果在关闭互联网的情况下打开该应用程序,即使打开了该应用程序,它也永远不会连接)。在这种情况下,有什么办法可以重试?
我尝试了http retry包,但它给了我15个以上的错误。
答案 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查找可以多次尝试异步操作的函数。