Dart获取API数据时如何用传统循环替代map方法解析JSON
问题核心
需要实现将JSON API返回数据存入普通列表的高性能Dart方案,替代资源消耗更高的map方法,原有自行编写的循环版本运行时报错Class List has no instance getter 'keys',需要与原有map逻辑完全等效的传统循环实现。
报错原因
json.decode(response.body)解码JSON数组格式的返回值时,输出类型是List<dynamic>而非键值对Map,因此不存在keys属性,原有循环写法按照Map结构遍历,和实际数据结构不匹配;同时写法中{jsonDecoded[k]}会创建Set包裹单个元素,和原逻辑直接调用DogClass.fromJson转换的逻辑不符。
等效循环实现代码
以下代码和原有map版本逻辑完全一致,使用传统for-in循环实现,额外补充了client关闭逻辑避免资源泄漏,同时修复了全局列表可能残留旧数据的问题:
Future<List<dynamic>> fetchDataFor(url) async { var client = http.Client(); try { final response = await client.get(Uri.parse(url)); await Future.delayed(Duration(seconds: 2)); if (response.statusCode == 200) { // 明确指定解码结果为列表类型 var jsonDecoded = json.decode(response.body) as List<dynamic>; // 初始化空列表,避免全局变量残留历史数据 final List<DogClass> BreedList = []; // 遍历列表每个元素做转换,和map逻辑完全对齐 for (final data in jsonDecoded) { BreedList.add(DogClass.fromJson(data)); } glossarList = BreedList; return BreedList; } else { throw Exception('Failed to load data'); } } finally { // 关闭http客户端释放资源 client.close(); } }
额外效率提升建议
- 若接口返回数据长度固定,可提前预分配列表内存:使用
final BreedList = List<DogClass>.empty(growable: true)..length = jsonDecoded.length预分配空间,减少列表动态扩容的性能损耗。 - 若不需要保留
glossarList和BreedList的双向绑定,可直接做对象拷贝而非引用赋值,减少状态异常带来的额外排查成本。 - 无特殊测试需求时可移除
Future.delayed模拟等待逻辑,减少不必要的等待开销。
内容的提问来源于stack exchange,提问作者Lash
相关产品推荐
相关产品推荐

