You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Dio调用API时遭遇Bad state: Future already completed错误求助

排查Dio调用API时"Error: Bad state: Future already completed"错误

问题重现

使用Dio调用API时触发错误:

Error: Bad state: Future already completed

对应的实现代码:

Future _getHomeData() async {
  try {
    var homeDataResponse = await HomeService().getHomeData();

    final classList = (homeDataResponse.data['classes']) as List;
    classes = classList.map((i) => ClassModel.fromJson(i)).toList();
    _storageService
        .writeSecureData(StorageItem("user_classes", jsonEncode(classes)));

    final examList = (homeDataResponse.data['exams']) as List;
    exams = examList.map((i) => Exam.fromJson(i)).toList();
    _storageService
        .writeSecureData(StorageItem("user_exams", jsonEncode(exams)));

    final taskList = (homeDataResponse.data['tasks']) as List;
    tasks = taskList.map((i) => Task.fromJson(i)).toList();
    _storageService
        .writeSecureData(StorageItem("user_tasks", jsonEncode(exams)));

    // for (var subject in subjects) {
    //   print("SUBJECtS ${subject.subjectName}");
    // }
  } catch (error) {
    if (error is DioError) {
      throw Result.error(error.response?.data['message']);
    } else {
      throw Result.error(error.toString());
    }
  }
}

错误原因分析

"Future already completed"错误的核心是同一个Completer实例被多次调用完成方法,结合当前代码场景,可能的触发点:

  • _storageService.writeSecureData内部实现问题:如果该方法里的Completer被重复调用complete/completeError,比如异步逻辑处理不当,或同一存储操作被重复触发。
  • 方法重复调用导致状态冲突:如果_getHomeData被多次触发(比如页面初始化时重复调用),多个异步操作同时修改classes/exams/tasks等共享变量,或同时调用存储服务,引发内部Future状态冲突。
  • 代码笔误(次要):最后一行存储user_tasks时,传入的是jsonEncode(exams)而非jsonEncode(tasks),这会导致存储数据错误,但不会直接触发Future错误,需修正。

解决办法

  1. 检查writeSecureData实现:
    确认方法内部的Completer仅被调用一次完成方法,避免在异步回调中重复触发;若使用第三方存储库,确保版本兼容,或更换为flutter_secure_storage等成熟库。
  2. 防止_getHomeData重复调用:
    添加调用锁,用布尔变量标记执行状态:
    bool _isLoading = false;
    
    Future _getHomeData() async {
      if (_isLoading) return;
      _isLoading = true;
      try {
        // 原有业务逻辑
      } finally {
        _isLoading = false;
      }
    }
    
  3. 修正存储数据笔误:
    将最后一行的jsonEncode(exams)改为jsonEncode(tasks):
    _storageService.writeSecureData(StorageItem("user_tasks", jsonEncode(tasks)));
    
  4. 异步存储操作添加await:
    当前代码未给writeSecureData加await,多个异步存储并行可能引发内部状态问题,建议添加await确保顺序执行:
    await _storageService.writeSecureData(StorageItem("user_classes", jsonEncode(classes)));
    // 其余存储操作同理
    

内容的提问来源于stack exchange,提问作者Nikola Jovanovic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 19:52:46