Flutter - whenComplete() 在使用提供程序时无法按预期工作

Flutter - whenComplete() not working as expected when using Providers

我正在尝试在执行 API 请求时显示加载,并在完成时显示带有响应的列表或显示消息的自定义小部件 (EmptyListWidget)。问题是在异步函数完成之前正在执行 whenComplete() 方法。

我也尝试过使用 then() 和 FutureBuilder,但我也无法使用 Provider 使其工作(总是 returns null)。

如果有人能提供帮助,我将不胜感激..谢谢:)

我的列表小部件:

class _AbsencesListState extends State<AbsencesList> {
  bool _isLoading = false;
  bool _isInit = true;

  @override
    void didChangeDependencies() {
    super.didChangeDependencies();
    if (_isInit) {
      setState(() => _isLoading = true);
      Provider.of<AbsencesTypes>(context, listen: false)
          .getAbsencesTypes(widget.ctx)
          .whenComplete(() {
        setState(() => _isLoading = false);
      });
      _isInit = false;
    }
  }
  
  @override
  Widget build(BuildContext context) {
    final absences = Provider.of<Absences>(context).items;
    return Stack(
      children: [
        _isLoading
            ? const Center(child: CircularProgressIndicator())
            : absences.length > 0
                ? Container()
                : EmptyListWidget(ListType.InconsistenciesList),
        ListView.builder(
          itemBuilder: (_, index) {
            return GestureDetector(
              onTap: () {},
              child: Card(
                elevation: 2.0,
                child: ListTile(
                  leading: CircleAvatar(
                    child: const Icon(Icons.sick),
                    backgroundColor: Theme.of(context).accentColor,
                    foregroundColor: Colors.white,
                  ),
                  title: Padding(
                    padding: const EdgeInsets.only(top: 3),
                    child: Text(absences[index].absenceType.name),
                  ),
                  subtitle: Text(
                    absences[index].firstDate
                  ),
                ),
              ),
            );
          },
          itemCount: absences.length,
        )
      ],
    );
  }
}

异步函数:

class AbsencesTypes with ChangeNotifier {
  List<AbsenceType> _absencesTypesList = [];

  List<AbsenceType> get items {
    return [..._absencesTypesList];
  }

  void emptyAbsencesTypeList() {
    _absencesTypesList.clear();
  }

  Future<void> getAbsencesTypes(BuildContext context) async {
    SharedPreferences _prefs = await SharedPreferences.getInstance();
    String token = _prefs.getString(TOKEN_KEY);
    http.get(
      API_URL,
      headers: {"Authorization": token},
    ).then(
      (http.Response response) async {
        if (response.statusCode == 200) {
          final apiResponse = json.decode(utf8.decode(response.bodyBytes));
          final extractedData = apiResponse['content'];
          final List<AbsenceType> loadedAbsencesTypes = [];
          for (var absenceType in extractedData) {
            loadedAbsencesTypes.add(
              AbsenceType(
                id: absenceType["id"],
                name: absenceType["name"].toString(),
                code: absenceType["code"].toString(),
                totalAllowedDays: absenceType["totalAllowedDays"],
              ),
            );
          }
          _absencesTypesList = loadedAbsencesTypes;
        } else if (response.statusCode == 401) {
          Utility.showToast(
              AppLocalizations.of(context).translate("expired_session_string"));
          Utility.sendUserToLogin(_prefs, context);
        }
        notifyListeners();
      },
    );
  }
}

您的问题可能是您在没有等待结果的情况下调用 http.get
getAbsencesTypes returns Future<void> 一旦 http.get 方法被执行,而不等待答案,它会导致你的 onComplete 方法被触发.

一个简单的解决方法是在 http.get 之前添加 await 关键字,但您可以做得更好。

在您的代码中,您没有完全使用可以解决您的问题的 ChangeNotifierProvider。您应该查看 Consumer class,这对您很有用,但由于这不是您最初的问题,我不会更深入地讨论这个主题。