Flutter双层for in循环嵌套await查询Firestore时遍历顺序异常问题
问题原因
你遇到的遍历顺序异常,核心是Dart 异步迭代的执行逻辑和实际代码写法不匹配,90%以上的这类问题都是你实际运行的代码中,外层循环用了forEach而非标准for-in:Dart的forEach不会等待异步回调执行完成,所有外层品牌的迭代会同时触发,每个迭代的第一个驾驶风格查询(sport)会先发起,所以所有品牌的sport查询结果会先集中返回,之后才是comfort、offroad的结果,就出现了你看到的顺序反转现象。
另外你贴的代码中getVotes函数定义的入参brand、drivingStyle完全没有被使用,属于无效参数,也建议清理。
修复方案
严格使用标准双层for-in循环,保证内层查询串行执行,单个品牌的所有驾驶风格查询完成后再处理下一个品牌,修正后代码如下:
List<String> brands = [ 'ferrari', 'porshe', 'lamborgini', 'bugatti', 'bentley', ]; List<String> drivingStyles = [ 'sport', 'comfort', 'offroad', ]; // 清理无用入参 Future getVotes() async { try { // 禁止替换为brands.forEach((brand) async {})写法,forEach不等待异步回调 for (String brand in brands) { // 存储当前品牌的所有驾驶风格投票数据 Map<String, int> currentBrandVotes = {}; for (String drivingStyle in drivingStyles) { var query = FirebaseFirestore.instance .collection('survey') .doc('car_survey') .collection('summer') .where('brand', isEqualTo: brand) .where('drivingStyle', isEqualTo: drivingStyle); // await会等待当前查询完成再执行下一个内层循环 var querySnapshot = await query.get(); var numberOfVotes = querySnapshot.docs.length; currentBrandVotes[drivingStyle] = numberOfVotes; print('brand: $brand, drivingStyle: $drivingStyle, votes: $numberOfVotes'); } // 单个品牌所有驾驶风格查询完成后再执行存储逻辑 // 这里替换为你自己的存储方法 await saveBrandSurveyData(brand, currentBrandVotes); } } catch (e) { print('getVotes ERROR: $e'); } } // 调用getVotes的位置必须加await,否则不会等待整个统计流程执行完成 void startSurveyCount() async { await getVotes(); print('所有品牌投票统计完成'); }
补充说明:如果需要兼顾查询效率和顺序,可以按品牌分组创建Future列表,整组并行查询后等待整组返回,再处理下一个品牌即可,不会改变处理顺序的同时提升查询速度。
内容的提问来源于stack exchange,提问作者AturicLiqr
相关产品推荐
相关产品推荐

