深入了解Flutter的isolate(1) ---- 事件循环(event loop)及代码运行顺序

栏目: IOS · 发布时间: 5年前

内容简介:接触过Flutter的人都知道,Flutter是用Dart来写的,Dart没有进程和线程的概念,所有的Dart代码都是在isolate上运行的,那么isolate到底是什么?本系列的文章将详细讨论。这篇文章讨论事件队列(event loop)及Dart代码运行顺序。我们对Dart代码进行分类:同步代码和异步代码; 我们在写Dart代码的时候,就只有两种代码,这两类代码是不同的:

接触过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大致的运行图:

深入了解Flutter的isolate(1) ---- 事件循环(event loop)及代码运行顺序

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

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

深入了解Flutter的isolate(1) ---- 事件循环(event loop)及代码运行顺序

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

  1. 先查看MicroTask queue是不是空的,不是的话,先运行microtask
  2. Microtask queue空了之后,在判断Event queue是不是空的,不是的话,运行event
  3. Event queue空了之后,在继续第1步

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

1. MicroTask

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

// Adds a task to the 先查看MicroTask queue.
scheduleMicrotask((){
  // ...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'));
  scheduleMicrotask(() => print('microtask #3 of 3'));
  print('main #2 of 2');
}
复制代码
  1. 首先运行同步代码

    所以是:

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

    Dart的异步队列不是我们平常想的那样,一边往队列里加task,一边运行,而是先往队列里添加task,所有task添加完毕,才会运行,所以 Future 的task就添加到 event queue ,而 scheduleMicrotask 添加到 microtask queue

  3. microtask queue

    这里就是:

    microtask #1 of 3
    microtask #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的执行顺序

      这里就是:

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

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

最后的结果就是:

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

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

PHP基础教程

PHP基础教程

厄尔曼 / 贾菡、刘彦博 / 人民邮电出版社 / 2010-1 / 49.00元

《PHP基础教程(第3版)》非常通俗易懂地向初学者介绍了PHP语言的基本概念、使用方法和注意事项。全书通过丰富的示例,引领读者逐步掌握这门流行的Web开发语言,使读者能够上手亲自编写适用于常用场景的PHP脚本。《PHP基础教程(第3版)》适合有基本的HTML经验的读者阅读。 点击链接进入新版: Web开发系列:PHP基础教程(第4版)一起来看看 《PHP基础教程》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具