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

