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);
关键优化说明
- 提前获取存储目录:把
getExternalStorageDirectory()移到循环外,减少重复调用。 - 用Future.wait等待所有异步任务:
list.map返回一个Future列表,Future.wait会等待所有Future执行完成后才继续后续代码,确保所有isPresent都被赋值。 - 移除冗余的IO操作:直接使用
await exists()获取异步结果,不需要再调用同步的existsSync()。 - 空安全处理:增加了
directory为null的判断,避免空指针异常。
内容的提问来源于stack exchange,提问作者Dhananjay Gahiwade
相关产品推荐
相关产品推荐

