簡體   English   中英

Flutter, Dart 無響應時重試Http Get請求

[英]Retry Http Get request if there is no response in Flutter, Dart

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

上述函數用於獲取頁面的 HTML 代碼,但在某些情況下會失敗。 該功能有時永遠不會完成,它會永遠等待獲得響應(例如,如果在互聯網關閉時打開應用程序,即使打開它,它也永遠不會連接)。 在這種情況下有沒有辦法重試?

我嘗試了 http 重試包,但它給了我 15 個以上的錯誤。

如何做到這一點的示例代碼:

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

您可以使用 http 包中的 RetryPolicy 重試連接,只需創建自己的類並繼承表單 RetryPolicy 並覆蓋這些函數,如下例所示,然后使用 HttpClientWithInterceptor.build 創建一個客戶端並添加您的自定義 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/);

還有一個包可以檢查互聯網連接,如果你的問題,請參閱連接

您可以像在同步代碼中一樣在異步函數中使用 try-catch 塊。 也許您可以在函數中添加某種錯誤處理機制,並在出錯時重試該函數? 這是有關該文件的一些文檔

文檔中的示例:

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

您還可以根據此 github 問題捕獲特定的異常

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

編輯:這也可能有幫助。

在此期間,請在此處查找可根據需要多次嘗試異步操作的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM