直到封闭函数返回时,setState()才执行 [英] setState() doesn't execute until the enclosing function returns
问题描述
所以我在颤抖中尝试这段代码:
void main()=>runApp(MyApp());MyApp类扩展了StatefulWidget {@override_MyAppState createState()=>_MyAppState();}类别_MyAppState扩展了State< MyApp>{int _i = 1;@override窗口小部件build(BuildContext context){返回MaterialApp(家:脚手架(身体:中心(子:MaterialButton(孩子:Text('You Pressed Me $ _i'),onPressed:(){setState((){_i ++;print('inside i = $ _i');});sleep(Duration(seconds:10));_i ++;print('outside i = $ _i');}),),),);}}
预期的行为(运行并按一次按钮之后):该按钮显示文字您按下了我2" ,
和变量 _i 然后增加到3,而不会影响视觉效果.
实际行为:执行 setState()
,然后再次增加 _i ,并且没有视觉变化,即屏幕上的文本没有更新,并在 onPressed()返回时, setState()导致小部件重建并更新屏幕,这是10秒钟后出现在屏幕上的内容:您按下了我3" .
So I was trying this code in flutter:
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _i = 1;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: MaterialButton(
child: Text('You Pressed Me $_i'),
onPressed: () {
setState(() {
_i++;
print('inside i = $_i');
});
sleep(Duration(seconds: 10));
_i++;
print('outside i = $_i');
}
),
),
),
);
}
}
Expected behavior(after running and pressing the button once): the button shows text "You Pressed Me 2",
and the variable _i then gets incremented to 3 without affecting the visual result.
Actual behavior: setState()
is execued and then _i is incremented again and no visual change happens i.e. the text on screen doesn't update, and when onPressed() returns, setState() causes the widget to rebuild and the screen updates and this is what appears on screen after 10 seconds: "You Pressed Me 3".
There is this quote from the docs about setState():
The provided callback is immediately called synchronously. It must not return a future (the callback cannot be async), since then it would be unclear when the state was actually being set.
I understand that the call is synchronous (so it's blocking, according to this answer) so it should return first (and this already happens) and then update the screen (or schedule that for some time in the future) and then return control to the following line (the latter 2 things don't happen).
I even tried it without the sleep but same result.
so what am I missing or misunderstanding?
Event Loop
There is something called Event Loop
Event Loop process Events in order
You have two events in order
Event A => Click => by the User
0.onPressed: () {
1.setState(() {
3. i++
4. Mark as widget dirty
5. Add to the global dirty widgets list
});
6.i++
});
Event B => Vsync signal => provided by the OS
7. check dirty widgets list
8. repaint
More
Here a YouTube video from Flutter in Focus series
-
- by flutter team member Andrew Brogdon (@RedBrogdon)
-
Or read it here
Ref.:
markNeedsBuild method - Element class - widgets library - Dart API
scheduleBuildFor method - BuildOwner class - widgets library - Dart API
drawFrame method - WidgetsBinding class - widgets library - Dart API
handleDrawFrame method - SchedulerBinding class - scheduler library - Dart API
buildScope method - BuildOwner class - widgets library - Dart API
optimization - What is the optimal render loop in Dart 2? - Stack Overflow
14 .dart engine - Google Search
scheduleFrame method - SchedulerBinding class - scheduler library - Dart API
packages/flutter/lib/scheduler.dart - external/github.com/flutter/flutter - Git at Google
这篇关于直到封闭函数返回时,setState()才执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!