簡體   English   中英

如何在 flutter 的 initState 中調用異步方法

[英]How to call an async method in initState in flutter

我需要從端點獲取一些信息。 我有這個方法:

List<Widget> cardsList = List();
List<dynamic> cardsId = List();

addToList() async {
    var jsonData = await Provider.of<CardData>(context).cardsList;
    print(jsonData);
    for (var i = 0, len = jsonData.length; i < len; i++) {
      if (jsonData[i]['account_type'] == "1") {
        cardsList.add(
          BankCard(
            bankName: jsonData[i]['title'],
            colors: [Color(0xFFD00E00), Color(0xFFF44336)],
            cardNumber: jsonData[i]['number'],
            cardDesc: jsonData[i]['description'],
          ),
        );
        cardsId.add(jsonData[i]['id']);
      }
    }
  }

和一個 class 作為提供者數據,稱為 CardData:

import 'package:flutter/material.dart';

import '../cards/cards.dart';

class CardData extends ChangeNotifier {
  static Cards cards = Cards();

  Future<dynamic> cardsList = cards.getCards();
}

和一個名為 Card 的 class 發送請求並執行所有其他操作:

import 'dart:convert';

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

class Cards {
  String _accessToken;
  String _refreshToken;

  Future<dynamic> getCards() async {
    SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
    _accessToken = sharedPreferences.getString("access");
    _refreshToken = sharedPreferences.getString("refresh");
    var jsonData;

    var response = await sendRequestToGetCards(
        url: "http://10.0.2.2:8000/accounts/list/", accessToken: _accessToken);
    if (response.statusCode == 200) {
      jsonData = json.decode(utf8.decode(response.bodyBytes));
      return jsonData;
    } else if (response.statusCode == 401) {
      _accessToken = await getNewAccessToken(_refreshToken);
      response = await sendRequestToGetCards(
          url: "http://10.0.2.2:8000/accounts/list/",
          accessToken: _accessToken);
      if (response.statusCode == 200) {
        jsonData = json.decode(utf8.decode(response.bodyBytes));
        return jsonData;
      }
    }
  }

  getNewAccessToken(String refreshToken) async {
    var refreshResponse = await http.post(
        "http://10.0.2.2:8000/users/api/token/refresh/",
        body: {'refresh': refreshToken});
    if (refreshResponse.statusCode == 200) {
      var jsonData = json.decode(refreshResponse.body);
      return jsonData['access'];
    }
  }

  sendRequestToGetCards({String url, String accessToken}) async {
    var response = await http.get(
      url,
      headers: {"Authorization": "Bearer $accessToken"},
    );
    return response;
  }
}

但是當我在initState中調用addToList方法在 build 方法之前檢索數據時,主 UI 消失了。

它出什么問題了?

您可以在 initState 中調用異步 function,但由於它本身不是異步 function,因此在繼續構建方法之前,它不會等待期貨完成,這就是您的 UI 消失的原因,因為它正在構建時沒有數據,所以有沒有卡。 我建議在您的構建方法中使用FutureBuilder在異步 function 返回時進行構建。

暫無
暫無

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

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