Flutter开发进阶:Flutter事件循环机制与异步

2022-03-17  本文已影响0人  __Null

Dart是基于 事件循环机制的单线程模型, 所以Dart中没有多线程, 也就没有主线程与子线程之分。

一、事件循环机制

对于用户点击, 滑动, 硬盘IO访问等事件, 你不知道何时发生或以什么顺序发生, 所以得有一个永不停歇且不能阻塞的循环来等待处理这些 "突发" 事件. 于是, 基于 事件循环机制 的 单线程模型 就出现了。

Dart的事件循环机制由一个消息循环(Event Looper)和两个消息队列构成。两个消息队列分别是事件队列(Event Queue)和微任务队列(Microtask Queue)。

1.Event Looper

Dart在执行完main函数后, Event Looper就开始工作, Event Looper优先全部执行完 Microtask Queue中的event, 直到Microtask Queue为空时, 才会执行Event Looper中的 event, Event Looper为空时才可以退出循环。

2.Event Queue

对于外部事件, 一旦没有任何 microtask 要执行, Event loop 才会考虑 event queue 中的第一项, 并且将会执行它。

Future(() {
  // 事件任务
});
3.Microtask Queue

Microtask 一般用于非常短的内部异步动作, 并且任务量非常少, 如果微任务非常多, 就会造成 Event Queue 排不上队, 会阻塞 Event Queue 的执行(如: 用户点击没有反应). 所以, 大多数情况下优先考虑使用 Event Queue, 整个 Flutter 源代码仅引用 scheduleMicroTask() 方法 7 次.

scheduleMicrotask(() {
  // 微任务
});

二、Future

1. Future 实例有 3 个常用方法:
2.链式调用

Future 可以在 then()方法中返回另一个 Future 实例, 从而达到链式调用的效果, 这对那些有数据关联的网络请求很有用

3.其他

Future 除了默认构造器外, 还提供了几个常用的命名构造器:

三、async/await

1、基本使用

四、isolate

所有的 Dart 代码都是在 isolate 中运行的, 它就是机器上的一个小空间, 具有自己的私有内存块和一个运行着 Event Looper 的单个线程. 每个 isolate 都是相互隔离的, 并不像线程那样可以共享内存. 一般情况下, 一个 Dart 应用只会在一个 isolate 中运行所有代码, 但如果有特殊需要, 可以开启多个:

1、创建 isolate (Dart API)

Dart 默认提供了 Isolate.spawn(entryPoint, message) 用于开启 isolate, 通过源码可以知道形参 message 其实是 形参 entryPoint 对应的函数执行时需要的参数。
使用 Isolate.spawn(entryPoint, message) 开启 isolate, 并指定要执行的任务:

import 'dart:isolate';
main(List<String> args) {
  print("main start");
  Isolate.spawn(calc, 100);
  print("main end");
}

void calc(int count) {
  var total = 0;
  for (var i = 0; i < count; i++) {
    total += i;
  }
  print(total);
}
2、isolate 通信 (单向)

isolate 间可以一起工作的唯一方法是通过来回传递消息. 一般情况下, 子isolate 会将运行结果通过管道以消息的形式发送到 主isolate, 并在 主isolate 的 Event Looper 中处理该消息, 这时就需要借助 ReceivePort 来处理消息的传递了:

import 'dart:isolate';
main(List<String> args) async {
  print("main start");

  // 1. 创建管道
  var receivePort = ReceivePort();

  // 2. 创建isolate
  Isolate isolate = await Isolate.spawn(foo, receivePort.sendPort);

  // 3. 监听管道
  receivePort.listen((message) {
    print(message);
    // 不再使用时, 关闭管道
    receivePort.close();
    // 不再使用时, 将 isolate 杀死
    isolate.kill();
  });

  print("main end");
}

void foo(SendPort sendPort) {
  sendPort.send("Hello lqr");
}
3、创建 isolate (Flutter API)

Flutter 提供了更为方便的开启 isolate 的 API: compute() 函数. 以下是示例代码:

main(List<String> args) async {
  int result = await compute(powerNum, 5);
  print(result);
}

int powerNum(int num) {
  return num * num;
}
上一篇 下一篇

猜你喜欢

热点阅读