Flutter中async/await需热重载而.then无需的原因咨询
问题:Flutter中async/await与.then写法在setState中的差异
初始代码
String? userName = ""; String? userEmail = ""; AuthService authService = AuthService(); @override void initState() { // TODO: implement initState super.initState(); gettingUserData(); }
情况1:async/await写法(需热重载才能显示邮箱)
gettingUserData() async { setState(() async { userName = await HelperFunction.getUsername(); userEmail = await HelperFunction.getUseremail(); }); }
情况2:.then写法(无需热重载即可显示数据)
gettingUserData() { HelperFunction.getUseremail().then((value) { setState(() { userEmail = value; }); }); HelperFunction.getUsername().then((value) { setState(() { userName = value; }); }); }
疑问:为何两种写法会出现是否需要热重载的差异?
原因分析
1. async/await写法的问题根源
setState的回调被定义成了异步函数,但Flutter的setState并不支持异步回调。setState的设计逻辑是接收同步的VoidCallback,执行回调内的同步代码后立即标记组件需要重建。
在错误的async/await写法中,setState会立刻执行回调里的代码(发起await请求),然后马上触发一次UI重建,但此时userName和userEmail还没被异步操作赋值。等后续异步操作完成、变量被赋值后,没有再次调用setState通知UI更新,所以新数据不会自动显示,必须手动热重载触发重建才能看到。
2. .then写法的正确逻辑
.then写法中,每个异步操作完成(拿到数据)的瞬间,都会在.then回调里调用setState。这意味着数据一获取到,就会立即通知Flutter更新UI,所以不需要热重载就能自动显示新数据。
正确的async/await写法
如果想用async/await,应该把异步操作放在setState外面完成,再调用同步的setState更新状态:
gettingUserData() async { // 先完成异步数据获取 final name = await HelperFunction.getUsername(); final email = await HelperFunction.getUseremail(); // 再调用setState更新UI setState(() { userName = name; userEmail = email; }); }
这种写法下,异步操作完成后才触发setState,Flutter会正确重建UI显示新数据,同样不需要热重载。
内容的提问来源于stack exchange,提问作者mohitnx
相关产品推荐
相关产品推荐

