Flutter Dart中的异步
以下内容从官网得到:
https://webdev.dartlang.org/articles/performance/event-loop
Even-Looper
Dart是单线程模型,也就没有了所谓的主线程/子线程之分。
Dart也是Event-Looper以及Event-Queue的模型,所有的事件都是通过EventLooper的依次执行。
而Dart的Event Loop就是:
- 从EventQueue中获取Event
- 处理Event
- 直到EventQueue为空

而这些Event包括了用户输入,点击,Timer,文件IO等

单线程模型
一旦某个Dart的函数开始执行,它将执行到这个函数结束,也就是Dart的函数不会被其他Dart代码打断。
Dart中没有线程的概念,只有isolate,每个isolate都是隔离的,并不会共享内存。而一个Dart程序是在Main isolate的main函数开始,而在Main函数结束后,Main isolate线程开始一个一个(one by one)的开始处理Event Queue中的每一个Event。

Event Queue以及Microtask Queue
Dart中的Main Isolate只有一个Event Looper,但是存在两个Event Queue:Event Queue以及Microtask Queue
Microtask Queue存在的意义是:
希望通过这个Queue来处理稍晚一些的事情,但是在下一个消息到来之前需要处理完的事情。
当Event Looper正在处理Microtask Queue中的Event时候,Event Queue中的Event就停止了处理了,此时App不能绘制任何图形,不能处理任何鼠标点击,不能处理文件IO等等
Event-Looper挑选Task的执行顺序为:
- 优先全部执行完Microtask Queue中的Event
- 直到Microtask Queue为空时,才会执行Event Queue中的Event

Dart中只能知道Event处理的先后顺序,但是并不知道某个Event执行的具体时间点,因为它的处理模型是一个单线程循环,而不是基于时钟调度(即它的执行只是按照Event处理完,就开始循环下一个Event,而与Java中的Thread调度不一样,没有时间调度的概念),也就是我们既是指定另一个Delay Time的Task,希望它在预期的时间后开始执行,它有可能不会在那个时间执行,需要看是否前面的Event是否已经Dequeue。
异步任务调度
当有代码可以在后续任务执行的时候,有两种方式,通过dart:async这个Lib中的API即可:
- 使用Future类,可以将任务加入到Event Queue的队尾
- 使用scheduleMicrotask函数,将任务加入到Microtask Queue队尾
当使用EventQueue时,需要考虑清楚,尽量避免microtask queue过于庞大,否则会阻塞其他事件的处理

使用Future
一般常用的Future构造函数:
new Future((){
// doing something
});
而一般常用的还有当有分治任务时,需要将一个大任务拆成很多小任务一步步执行时,就需要使用到Future.then函数来拆解任务
void main(){
new Future(() => futureTask) // 异步任务的函数
.then((m) => "futueTask execute result:$m") // 任务执行完后的子任务
.then((m) => m.length) // 其中m为上个任务执行完后的返回的结果
.then((m) => printLength(m))
.whenComplete(() => whenTaskCompelete); // 当所有任务完成后的回调函数
}
int futureTask() {
return ;
}
void printLength(int length) {
print("Text Length:$length");
}
void whenTaskCompelete() {
print("Task Complete");
}
当任务需要延迟执行时,可以使用new Future.delay来将任务延迟执行,而如上所述,只有当Main isolate的Event Queue处于Idle的状态时,才会延迟1s执行,否则等待的时间会比1s长很多
new Future.delayed(const Duration(seconds: ), () => futureTask);
当需要做动画的时候,不要使用Future,而需要使用animateFrame
PS:
- Future中的then并没有创建新的Event丢到Event Queue中,而只是一个普通的Function Call,在FutureTask执行完后,立即开始执行
- 当Future在then函数先已经执行完成了,则会创建一个task,将该task的添加到microtask queue中,并且该任务将会执行通过then传入的函数
- Future只是创建了一个Event,将Event插入到了Event Queue的队尾
- 使用Future.value构造函数的时候,就会和第二条一样,创建Task丢到microtask Queue中执行then传入的函数
- Future.sync构造函数执行了它传入的函数之后,也会立即创建Task丢到microtask Queue中执行
使用scheduleMicrotask
在最顶层的调用关系中,使用该函数即可
async.scheduleMicrotask(() => microtask());
void microtask(){
// doing something
}
使用isolate以及Worker
当有计算很繁重的任务时,则需要使用isolate或者Worker来执行,以保持App对用户操作的及时响应。Isolate的实现可能是一个单独的线程,或者一个单独的进程,需要看Dart VM是如何实现的。
Flutter Dart中的异步的更多相关文章
- dart系列之:dart中的异步编程
目录 简介 为什么要用异步编程 怎么使用 Future 异步异常处理 在同步函数中调用异步函数 总结 简介 熟悉javascript的朋友应该知道,在ES6中引入了await和async的语法,可以方 ...
- flutter中的异步机制Future
饿补一下Flutter中Http请求的异步操作. Dart是一个单线程语言,可以理解成物理线路中的串联,当其遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞,用户就会感觉到 ...
- flutter中的异步机制 Future
饿补一下Flutter中Http请求的异步操作. Dart是一个单线程语言,可以理解成物理线路中的串联,当其遇到有延迟的运算(比如IO操作.延时执行)时,线程中按顺序执行的运算就会阻塞,用户就会感觉到 ...
- [Dart] Flutter开发中的几个常用函数
几个Flutter开发中的常用函数 /** 返回当前时间戳 */ static int currentTimeMillis() { return new DateTime.now().millisec ...
- Dart语言之 异步支持
Dart类库有非常多的返回Future或者Stream对象的函数. 这些函数被称为异步函数:它们只会在设置好一些耗时操作之后返回,比如像 IO操作.而不是等到这个操作完成. async和await关键 ...
- [flutter+dart] windows7下开发环境的安装与配置
前言 博主是做嵌入式的,参加工作时间也不久,而且是非科班出身,之前从未接触过移动开发.最近了解到了flutter框架和dart语言,想作为第二语言学习一下,因此会从最基础的环节开始,以此博客作为记录, ...
- flutter 项目中,开发环境、多接口域名、多分支的配置
flutter 项目中,开发环境.多接口域名.多分支的配置 开发环境:配置成多个入口文件.比如:main.dart.main_develop.dart.main_preview.dart 多域名:每个 ...
- dart中extends、 implements、with的用法与区别
一.概述 继承(关键字 extends) 混入 mixins (关键字 with) 接口实现(关键字 implements) 这三种关系可以同时存在,但是有前后顺序: extends -> m ...
- 【Flutter 1-2】在 Windows 10下安装Flutter+Dart+Android Studio 配置Flutter开发环境
在 Windows 10下安装Flutter+Dart+Android Studio 配置Flutter开发环境 文章首发地址 配置环境变量 由于部分网站被墙的原因,我们需要先配置Flutter国内镜 ...
随机推荐
- centos7.2 部署zabbix 3.2.7
centos7.2 部署zabbix 3.2.7[zabbix@zabbixServer ~]$ cat /etc/redhat-release CentOS Linux release 7.2.15 ...
- docker学习实践之路[第四站]利用pm2镜像部署node应用
拉取keymetrics/pm2-docker-alpine:8镜像 docker pull keymetrics/pm2-docker-alpine: [8]为node镜像的版本号: 建立Docke ...
- 课程一(Neural Networks and Deep Learning)总结——1、Logistic Regression
---------------------------------------------------------------------------------------------------- ...
- 封装、构造方法、private、Static与this关键字、main()_Day07
1:成员变量和局部变量的区别(理解) (1)定义位置区别: 成员变量:定义在类中,方法外. 局部变量:定义在方法中,或者方法声明上. (2)初始化值的区别: 成员变量:都有默 ...
- shell 终端terminfo命令 tput
tput命令 tput 可以更改终端功能,如移动或更改光标,更改文本属性,清除终端屏幕的特定区域等. 光标属性 在shell脚本或命令行中,可以利用tput命令改变光标属性. tput clear # ...
- Apache版本的Hadoop HA集群启动详细步骤【包括Zookeeper、HDFS HA、YARN HA、HBase HA】(图文详解)
不多说,直接上干货! 1.先每台机器的zookeeper启动(bigdata-pro01.kfk.com.bigdata-pro02.kfk.com.bigdata-pro03.kfk.com) 2. ...
- 使用XHProf分析PHP性能瓶颈(一)
安装xhprof扩展 wget http://pecl.php.net/get/xhprof-0.9.4.tgz tar zxf xhprof-0.9.4.tgz cd xhprof-0.9.4/ex ...
- React技术栈梳理
一.react是什么? react是一个js框架,可以用它来编写html页面,使用react后我们可以完全抛弃html(只需要一个主index文件),而用纯js来编写页面: 二.为什么要使用react ...
- Vue笔记:使用 axios 发送请求
在Vue1.0的时候有一个官方推荐的 ajax 插件 vue-resource,但是自从 Vue 更新到 2.0 之后,官方就不再更新 vue-resource. 关于为什么放弃推荐? -> 尤 ...
- Java你不知道的那些事儿—Java隐藏特性(上)
每种语言都很强大,不管你是像我一样的初学者还是有过N年项目经验的大神,总会有你不知道的东西.就其语言本身而言,比如Java,也许你用Java开发了好几年,对其可以说是烂熟于心,但你能保证Java所有的 ...