博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入了解Flutter的isolate(1) ---- 事件循环(event loop)及代码运行顺序
阅读量:6880 次
发布时间:2019-06-27

本文共 3336 字,大约阅读时间需要 11 分钟。

前言

接触过Flutter的人都知道,Flutter是用Dart来写的,Dart没有进程和线程的概念,所有的Dart代码都是在isolate上运行的,那么isolate到底是什么?本系列的文章将详细讨论。这篇文章讨论事件队列(event loop)及Dart代码运行顺序。

0x00 同步代码和异步代码

我们对Dart代码进行分类:同步代码和异步代码; 我们在写Dart代码的时候,就只有两种代码,

  • 同步代码:就是一行行写下来的代码
  • 异步代码:就是以Future等修饰的代码

这两类代码是不同的:

1.运行顺序不同

同步代码和异步代码运行的顺序是不同的:

先运行同步代码,在运行异步代码复制代码

就是,即使我异步代码写在最前面,同步代码写在最后面,不好意思,我也是先运行后面的同步代码,同步代码都运行完后,在运行前面的异步代码。

2.运行的机制不同

异步代码是运行在event loop里的,这是一个很重要的概念,这里可以理解成Android里的Looper机制,是一个死循环,event loop不断的从事件队列里取事件然后运行。

0x01 event loop 架构

下面是event loop大致的运行图:

这个很好理解,事件events加到Event queue里,Event loop循环从Event queue里取Event执行。

这个理解后,在看event loop详细的运行图:

从这里看到,启动app(start app)后:

  1. 先查看MicroTask queue是不是空的,不是的话,先运行microtask
  2. 一个microtask运行完后,会看有没有下一个microtask,直到Microtask queue空了之后,才会去运行Event queue 3.在Evnet queue取出一个event task运行完后,又会跑到第一步,去运行microtask

这里多了两个名词:MicroTaskEvent,这代表了两个不同的异步task

而且可以看出:

  • 如果想让任务能够尽快执行,就用MicroTask

1. MicroTask

这个大家应该不太清楚,但是这个也是dart:async提供的异步方法,使用方式:

// Adds a task to the 先查看MicroTask queue.scheduleMicrotask((){  // ...code goes here...}); 复制代码

或者:

new Future.microtask((){    // ...code goes here...});复制代码

2.Event

Event我们就很清楚了,就是Future修饰的异步方法,使用方式:

// Adds a task to the Event queue.new Future(() {  // ...code goes here...});复制代码

0x02

纯粹讲理论知识不太好理解,我们直接上代码,讲一个例子,看如下的代码,请问打印顺序是什么样的?

import 'dart:async';void main() {  print('main #1 of 2');  scheduleMicrotask(() => print('microtask #1 of 3'));  new Future.delayed(new Duration(seconds:1),      () => print('future #1 (delayed)'));  new Future(() => print('future #2 of 4'))      .then((_) => print('future #2a'))      .then((_) {        print('future #2b');        scheduleMicrotask(() => print('microtask #0 (from future #2b)'));      })      .then((_) => print('future #2c'));  scheduleMicrotask(() => print('microtask #2 of 3'));  new Future(() => print('future #3 of 4'))      .then((_) => new Future(                   () => print('future #3a (a new future)')))      .then((_) => print('future #3b'));  new Future(() => print('future #4 of 4'))  .then((_){    new Future(() => print('future #4a'));  })  .then((_) => print('future #4b'));  scheduleMicrotask(() => print('microtask #3 of 3'));  print('main #2 of 2');}复制代码
  1. 首先运行同步代码

    所以是:

    main #1 of 2main #2 of 2复制代码
  2. 接下来是异步代码

    Dart的Event Loop是先判断 microtask queue里有没有task,有的话运行microtaskmicrotask运行完后,在运行event queue里的event task,一个event task 运行完后,再去运行 microtask queue,然后在运行event queue

  3. microtask queue

    这里就是:

    microtask #1 of 3microtask #2 of 3复制代码
  4. event queue event queue还有有特殊的情况需要考虑:

    • Future.delayed

      需要延迟执行的,Dart是怎么执行的呢,是在延迟时间到了之后才将此task加到event queue的队尾,所以万一前面有很耗时的任务,那么你的延迟task不一定能准时运行

    • Future.then

      Future.then里的task是不会加入到event queue里的,而是当前面的Future执行完后立即掉起,所以你如果想保证异步task的执行顺序一定要用then,否则Dart不保证task的执行顺序

    • scheduleMicrotask

    一个event task运行完后,会先去查看Micro queue里有没有可以执行的micro task。没有的话,在执行下一个event task

    这里就是:```future #2 of 4future #2afuture #2bfuture #2cmicrotask #0 (from future #2b)future #3 of 4future #4 of 4future #4bfuture #3a (a new future)future #3bfuture #4afuture #1 (delayed)```复制代码

这里你肯定好奇为啥future #4 of 4future #3 of 4后面,因为 future #3 of 4的then里又新建了一个Future,所以这个task会加到event queue的最后面。

最后的结果就是:

main #1 of 2main #2 of 2microtask #1 of 3microtask #2 of 3microtask #3 of 3future #2 of 4future #2afuture #2bfuture #2cmicrotask #0 (from future #2b)future #3 of 4future #4 of 4future #4bfuture #3a (a new future)future #3bfuture #4afuture #1 (delayed)复制代码

参考文章

转载地址:http://gzfbl.baihongyu.com/

你可能感兴趣的文章
static 关键字和类的加载顺序
查看>>
安卓ListView基础应用
查看>>
【原创】PostgreSQL 快速创建空表TIPS
查看>>
利用PowerBI结合SCOM展示数据报表
查看>>
中学时代的记忆---老师的黑板
查看>>
Horizon View 6-View Connection Server部署⑴
查看>>
iptables 实战演练
查看>>
Python 学习笔记 - 线程(线程锁,信标,事件和条件)
查看>>
RHEL6基础四十一之selinux和iptables基础
查看>>
数据结构之单链表在第i个元素之前插入元素的算法
查看>>
Exchange Server 运维管理02:邮箱数据库存储原理
查看>>
Exchange Server2013 系列十:证书的配置
查看>>
Cygwin新手必读
查看>>
52.本地VMware环境虚拟机的异地(Azure)容灾(下)
查看>>
也谈谈Apache与Nginx
查看>>
Word中使用正则表达式进行查找和替换
查看>>
jquery.autocomplete 搜索文字提示
查看>>
ADB用法
查看>>
Remote Desktop Organizer – 管理组织远程桌面 - 小众软件
查看>>
把图片保存到数据库里
查看>>