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

Flutter中如何更新List<Map<String,dynamic>>类型列表?

问题分析与解决方案

你的代码核心问题是异步操作的执行时机没把控好:forEach里的async回调不会阻塞后续代码,导致你在异步任务还没完成时就赋值并打印fileList,此时isPresent字段还没被正确设置。另外代码里还有冗余的异步调用,也需要优化。

错误点拆解

  • forEach的async回调是独立的异步任务,不会等待所有回调完成才执行后续的fileList = list和print(fileList),所以打印的还是未更新的列表。
  • 先调用await io.File(file.path).exists(),又用existsSync(),完全没必要,异步方法的结果没被利用,还多了一次IO操作。
  • getExternalStorageDirectory()在循环里重复调用,应该提前获取一次即可。

修正后的代码

// 先获取存储目录,只调用一次
final Directory? directory = await getExternalStorageDirectory();
if (directory == null) {
  // 处理目录获取失败的情况
  fileList = [];
  print('无法获取存储目录');
  return;
}

final List<Map<String, dynamic>> list = [...fetchJsonData['data']];
// 使用Future.wait等待所有异步任务完成
await Future.wait(list.map((item) async {
  final String filePath = "${directory.path}/${item['filename']}";
  // 直接用异步的exists()获取结果,避免同步阻塞
  final bool isExists = await io.File(filePath).exists();
  item['isPresent'] = isExists;
  print(isExists);
}));

fileList = list;
print(fileList);

关键优化说明

  1. 提前获取存储目录:把getExternalStorageDirectory()移到循环外,减少重复调用。
  2. 用Future.wait等待所有异步任务:list.map返回一个Future列表,Future.wait会等待所有Future执行完成后才继续后续代码,确保所有isPresent都被赋值。
  3. 移除冗余的IO操作:直接使用await exists()获取异步结果,不需要再调用同步的existsSync()。
  4. 空安全处理:增加了directory为null的判断,避免空指针异常。

内容的提问来源于stack exchange,提问作者Dhananjay Gahiwade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:42:22