如何让map()在函数返回前执行,除print外有什么更优实现方案?
根因说明
Dart 中Iterable的map方法是懒加载的,只有当你主动遍历返回的迭代器、或者调用toList()/toSet()/join()这类消耗迭代器的方法时,map传入的回调才会执行。你之前用print包裹能生效,本质是print会调用迭代器的toString方法,触发了全量遍历,属于歪打正着的hack写法,显然不是合理方案。另外你的逻辑全是同步操作,完全不需要用到Future.wait,这个API是用来处理多个异步任务等待场景的,和你的问题不匹配。
实现方案
方案1:最小改动,替换map为forEach
forEach会立即遍历所有元素,不需要额外触发迭代,也不需要依赖print的副作用,只要把原代码里的map替换为forEach、删掉外层print即可:
List<Student> foo(){ int i = -1; studentDataMap.values.forEach( (entry) { i++; if (studentIds.contains(entry['id'])) { studentsList.add(Student.fromRTDB( entry as Map, studentDataMap.keys.elementAt(i))); } }, ); return studentsList; }
方案2:更推荐的无副作用写法
直接遍历Map的entries同时获取键值对,不需要自己维护索引计数器,也不用依赖外部的studentsList变量,逻辑更清晰、出错概率更低:
List<Student> foo() { return studentDataMap.entries // 先过滤出ID在目标列表内的条目 .where((entry) => studentIds.contains(entry.value['id'])) // 转换为Student对象 .map((entry) => Student.fromRTDB(entry.value as Map, entry.key)) // 立即触发迭代生成List .toList(); }
注意事项
map的设计初衷是做1:1的元素转换,不要用它来执行修改外部变量这类带副作用的逻辑,遍历执行副作用优先用forEach或者普通for循环- 自行维护索引计数器的写法容易出现索引越界、计数错误的问题,能直接获取对应键值的场景优先用
Map.entries遍历
内容的提问来源于stack exchange,提问作者Manraj Singh
相关产品推荐
相关产品推荐

