Flutter教程- Async(一) 事件循环Event Loop机制


发文时间:2022年04月13日 11:33:59     编辑:Aaron      标签:Flutter异步(Async) 图文详解系列 993


走进Dart单线程不卡顿的核心原理:Event Loop机制,并介绍Event Queue 和 Microtask Queue 的概念。

本系列前言

  本教程是跟着B站up主"王叔不秃"作者的视频教程所写,如有需可访问 此链接 作为王叔的粉丝,强烈推荐大家观看学习! 以下为本人所写的学习笔记,但愿可以帮到大家~

正文开始

一、实现异步的方式

 void _incrementCounter() async {
    await Future.delayed(Duration(seconds: 1));
    setState(() {
      _counter++;
    });
  }

  void _incrementCounter2(){
    Future.delayed(Duration(seconds: 1), () {
      setState(() {
        _counter++;
      });
    });
  }
  
 void _incrementCounter3() {
    Future.delayed(Duration(seconds: 1)).then((value) => 
    setState(() {
      _counter++;
     }));
 }

  三种代码实现的功能都是一样的,都是异步的方式等待1秒,执行后面的加1操作,

其中async/await,Fluter.delayed回调都是Dart语法糖

二、异步操作并不是多线程

 2.1:Dart中的异步操作不是多线程,多线程为何不卡

  (1)、什么叫做卡?程序卡本质上来说就是程序没有时间来更新UI,就是不能及时更新屏幕

信息

   1、程序在处理很大的计算量,CPU忙不过来

   2、可能是在等待服务器的数据响应,或文件读写等。

  (2)、多线程(Multithreading)

     每当遇到需要等待的东西,单独派一个线程去守着,这样执行UI操作的主线程就不

会等待卡顿了

  (3)Dart解决思路

    1、Dart中每一个线程都封装在一个Isolate里,每个进程不能互相共享内存,如果想要通信只能通过发消息的方式

    2、线程无法共享变量,一个线程的变量就不会被另一个线程修改

    3、每个线程非常独立,Dart的GC也可以做到非常高效。Flutter中Widget会不停被创建摧毁

    4、Dart中每个线程隔离后,开发者操作起来异常麻烦,但是我们在开发中只需要一个

Isolate,也就不需要多线程,一个线程就足够了

   

2.2:一个线程如何处理网络操作,或等待数据的情况

(1)事件循环(Event Loop)

   程序从main()开始执行,一般执行完全部代码就会退出,代码几百行一般不到一

秒就能全部执行完,app运行完不能就直接退出

   事件循环能够保证代码一直在循环不会轻易结束

(2)事件队列(Event Queue)

    循环主要任务是在检查Event Queue事件队列,在Event Queue如果发现有什么新

的事件,就要把代码送去执行

    所谓的异步操作实际上就是在Event Queue添加事件来完成的

    服务器请求会先产生一个Future,我们可以用Future/then的方法告诉程序,

等到这个Future完成时,需要执行什么方法。在这个Future还没执行完的时候,Event 

Loop就可以去忙别的事情

    程序在等服务器的一个回应,还没等到的时候用户点击了按钮,可以先执行用

户点击事件,这样就不会一直等待服务器响应造成死机

    除了服务器请求会得到一个Future,也可以手动往Event Queue里添加事件

 Future(() => print('A'));
        或者等待一秒 Future.delayed(Duration(seconds: 1), () => 
        print('A'))
        
        代码如下
   void main() {
        Future(() => print('A'));
        print('B');
      }
      
      /*
      思路:
        Future代表以后需要打印A,将事件放入Event Queue,代码继续执行
        立刻打印一个B。main执行完就会检查Event Queue有没有事件,
        查找到打印A的事件,所以会被立即执行。
        输出结果:
            B
            A
      */

(3)Microtask Queue

   级别比Event Queue更高,相当于迪士尼,机场的贵宾区,VIP通道

   只要Microtask Queue中还有事件没有执行完,Event Queue中一个事件都不会被执行。

只有全部的Microtask Queue都执行完,才有机会来执行Event Queue。

   Event Queue在执行中,只要Microtask Queue中有新任务进来,会立即执行Microtask

 Queue中的任务

    实战中一般不会往Microtask Queue中添加事件,Microtask Queue是交给Dart自己

来处理的,我们尽量不要干扰它的行为。如果人人都是VIP,那VIP也就没有存在的必要

    在Flutter引擎里面由大量的事件使用的Event Queue,如果由大量时间往Microtask

 Queue中挤,那Flutter有些事件也就不会执行

往Microtask Queue中插入事件

  void _incrementCounter4() async {
    scheduleMicrotask(() => print('A'));//案例
    Future(() => print('d'));
    Future.microtask(() => print('c'));//案例
    print('b');
  }
  
  /*
  使用scheduleMicrotask 要引入 import 'dart:async';
  输出结果如下:
B
A
C
D
  */

image.png

三、单进程存在问题

单进程时间循环机制只能解决循环问题,比如用户输入,操作数据库

如果确实因为计算量太大造成的卡顿,只能多造几个Isolate实现真正的多进程

四、总结

三种事件的添加方式

image.png



                                                                         will get better and better

 

若无特殊说明,此文章为博主原创。
写稿不易,如需转载,请注明出处: https://www.aaroner.cn/art/51.html




SITE MAP

  FOLLOW US