直到封闭函数返回时,setState()才执行 [英] setState() doesn't execute until the enclosing function returns

查看:54
本文介绍了直到封闭函数返回时,setState()才执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在颤抖中尝试这段代码:

  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

Ref.:

  1. setState method - State class - widgets library - Dart API

  2. markNeedsBuild method - Element class - widgets library - Dart API

  3. scheduleBuildFor method - BuildOwner class - widgets library - Dart API

  4. drawFrame method - WidgetsBinding class - widgets library - Dart API

  5. handleDrawFrame method - SchedulerBinding class - scheduler library - Dart API

  6. buildScope method - BuildOwner class - widgets library - Dart API

  7. dart engine loop - Google Search

  8. Dart Programming - Loops - Tutorialspoint

  9. optimization - What is the optimal render loop in Dart 2? - Stack Overflow

  10. Understanding Flutter Render Engine - Stack Overflow

  11. Technical overview - Flutter

  12. Flutter - Dart API docs

  13. flutter/spinning_square.dart at master · flutter/flutter

14 .dart engine - Google Search

  1. scheduler library - Dart API

  2. flutter/binding.dart at master · flutter/flutter

  3. scheduler library - Dart API

  4. frame scheduling flutter - Google Search

  5. scheduleFrame method - SchedulerBinding class - scheduler library - Dart API

  6. scheduler library - Dart API

  7. packages/flutter/lib/scheduler.dart - external/github.com/flutter/flutter - Git at Google

  8. flutter/spinning_square.dart at master · flutter/flutter

  9. dart engine - Google Search

  10. threading | Dart Package

  11. isolate flutter - Google Search

这篇关于直到封闭函数返回时,setState()才执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆