Flutter中本地存储含Characteristic列表的Product对象的存取问题
看起来你已经在Product类里写好了处理嵌套Characteristic列表的解码逻辑,只是在读取本地存储的时候踩了两个小坑:异步遍历的问题,以及没充分利用已经写好的fromJson工厂方法。下面给你一步步解决:
首先,你需要知道的关键事实
你在Product.fromJson里已经实现了characteristics的解码逻辑——它会遍历JSON里的characteristics数组,逐个调用Characteristic.fromJson生成对象并组装成列表。所以不需要额外写嵌套列表的解码代码,直接用这个工厂方法就行。
修复异步遍历的问题
你原来用forEach配合async回调的方式有问题:forEach不会等待每个异步操作完成,函数会直接走到return products这一步,此时products还是空的。我们可以用两种方式解决:
方式1:用for-in循环(串行获取,逻辑简单)
Future<List<Product>> getProductsFromSharedPrefs() async { String productIdsString = await Preference.getValue(key: "ProductIds"); // 处理空值情况,避免解码报错 if (productIdsString == null || productIdsString.isEmpty) { return []; } List<dynamic> productIdsList = json.decode(productIdsString); List<Product> products = []; // 用for-in循环确保等待每个异步读取操作完成 for (var productId in productIdsList) { String productString = await Preference.getValue(key: productId.toString()); if (productString != null) { final decodedProductJson = jsonDecode(productString); // 直接调用Product.fromJson,自动处理嵌套的characteristics products.add(Product.fromJson(decodedProductJson)); } } return products; }
方式2:用Future.wait(并行获取,效率更高)
如果产品数量较多,并行读取会更快:
Future<List<Product>> getProductsFromSharedPrefs() async { String productIdsString = await Preference.getValue(key: "ProductIds"); if (productIdsString == null || productIdsString.isEmpty) { return []; } List<dynamic> productIdsList = json.decode(productIdsString); // 把每个读取+解码操作包装成Future List<Future<Product?>> productFutures = productIdsList.map((productId) async { String productString = await Preference.getValue(key: productId.toString()); if (productString == null) return null; final decodedProductJson = jsonDecode(productString); return Product.fromJson(decodedProductJson); }).toList(); // 等待所有Future完成,过滤掉null值 List<Product?> results = await Future.wait(productFutures); return results.where((product) => product != null).cast<Product>().toList(); }
为什么这样能解决嵌套解码问题?
回顾你写的Product.fromJson:
factory Product.fromJson(Map<String, dynamic> json) { var characteristics = new List<Characteristic>(); json['characteristics'].forEach((v) { characteristics.add(Characteristic.fromJson(v)); }); return Product( id: json['id'], price: json['price'].toString(), description: json['description'], characteristics: characteristics, ); }
当你调用Product.fromJson(decodedProductJson)时,它会自动遍历JSON里的characteristics数组,把每个元素转换成Characteristic对象,最终组装成List<Characteristic>赋值给Product的characteristics属性——完全不需要你手动处理嵌套列表的解码!
内容的提问来源于stack exchange,提问作者Ehsan Askari
相关产品推荐
相关产品推荐

