Dart异步任务

异步任务

Dart 是单线程执行任务,支持异步操作

1.Isolate

2.Future

Isolate

通过lsolate实现异步操作

void main() {
  //将消息接收器中配合的发送器传给isolate
  Isolate.spawn(entryPoint, "发送的消息");
  Isolate.spawn(entryPoint, "发送的消息2");
  Isolate.spawn(entryPoint, "发送的消息3");
  print('继续运行');
}

void entryPoint(String msg) {
  print(msg);
}
//运行结果
继续运行
发送的消息
发送的消息2
发送的消息3

通过Isolate 可以将一个方法进行异步执行,我们就可以在entryPoint方法中执行一些耗时任务了。

平常在android 的开发过程中,有耗时任务执行还不够,还需要线程间的交互,例如子线程请求数据在UI线程更新页面之类的,同样在Dart中我们异步Isolate 和主Isolate进行(我们暂且这样称呼)也支持数据交互。由此,接收器 ReceivePort 就出现了,顾名思义接收器就是用来接收消息的,当然有接收器 也就有发射器 SendPort,每一个接收器 都会有对应的一个发射器。

void  main(){
  //接收器
  var receivePort = new ReceivePort();
  receivePort.listen((message) {
    print(message);
  });
  //发射器
  var sendPort = receivePort.sendPort;
  sendPort.send("测试消息");
}
//打印结果
测试消息

现在把Isolate 和 receivePort 结合起来使用,来完异步通信。

为了方便讲解,我们暂且分为 主lsolate和子lsolate。

既然为了通信,就需要住lsolate和子laolate 都需要持有对方的接收器,有了接收器 自然也就持有了发射器。

先将代码贴出:

void main() {
  late SendPort sendPort;
  //创建一个消息接收器
  var receivePort = new ReceivePort();
  //将消息接收器中配合的发送器传给isolate
  Isolate.spawn(entryPoint, receivePort.sendPort);
  //从消息接收器读取消息
  receivePort.listen((message) {
    //判断消息类型
    if (message is SendPort) {
      print('主线程发送器赋值');
      sendPort = message;
    }
    if (message is! SendPort) {
      print('主线程收到的消息↓↓↓↓');
      print(message);
    }
    if (message == 1) {
      sendPort.send("这是主线程发送给自线程的消息");
    }
  });
  print('继续运行');
}

void entryPoint(SendPort sendPort) {
  //创建接收器
  var receivePort = new ReceivePort();
  receivePort.listen((message) {
    print('子isolate 监听到的消息' + message);
  });
  //通过主lsolate的发送器 给主lsolate发送子lsolate的发送器
  sendPort.send(receivePort.sendPort);
  sleep(Duration(seconds: 5));
  sendPort.send("子线程发送的消息");
  sleep(Duration(seconds: 5));
  sendPort.send(1);
}

首先创建子lsolate

然后将主lsolate 创建的接收器所对应的发射器传给子lsolate

子lsolate创建接收器,然后将这个接收器所对应的发射器发送给主lsolate

现在,主lsolate有了自己的接收器,可以接受子lsolate 的消息,有子lsolate的发射器,可以向子lsolate发送消息;子lsolate有自己的接收器,可以接收主lsolate发送的消息,也有主lsolate 的发射器,可以想主lsolate发送消息(这方面可能有点绕,需要好好梳理一下)。

至此,主lsolate 和 子lsolate 就可以进行通信了。

Future

Future 对象表示异步操作的结果 执行异步任务,通常通过then()来处理返回的结果

void main() {
  Future future = Future.delayed(Duration(seconds: 3));
  future.then((value) {
    print('异步任务');
  });
  print('同步任务');
}
//执行结果
同步任务
异步任务

在这里是执行了延时3s的异步任务,通过结果可以看出耗时任务的执行并不会阻碍main方法的执行。

此外Future 还可进行异步任务的串联执行

void main() {
  Future future = Future.delayed(Duration(seconds: 3)).then((value) {
    print('异步任务1');
  });
  Future future2 = future.then((value) {
    sleep(Duration(seconds: 1));
    print('异步任务2');
  });
  future2.then((value) {
    sleep(Duration(seconds: 1));
    print('异步任务2');
  });
  print('同步任务');
}
//执行结果
同步任务
异步任务1
异步任务2
异步任务2

async 用于标明函数是一个异步函数,其返回的对象是一个Future 对象。

await 用来等待耗时操作的返回结果,这个操作会阻塞到后面的代码。

接下里就用Future来执行一个网络请求:

void main() {
  print('方法开始执行');
  get().then((value) {
    print(value);
  });
  print('方法执行末尾');
}

Future<Response> get() async {
  //网络访问
  Response response = await Dio().get("https://www.wanandroid.com/banner/json");
  return response;
}

//执行结果
方法开始执行
方法执行末尾
{"data":[{"des....省略

可以看出异步任务不会阻碍同步任务的执行。

最后补充一下,在Dart中提供了一种优先执行任务的任务队列:微任务队列

任务执行都是微任务队列优先

void main() {
  var receivePort = new ReceivePort();
  
  receivePort.listen((message) {
    print(message);
  });
  receivePort.sendPort.send("测试消息");
  Future.microtask(() => {
    print('微任务队列'),
    sleep(Duration(seconds: 3))
  });
}
//执行结果
微任务队列
测试消息

Dart异步任务

个人笔记,仅供参考,如有问题,欢迎指正,荣幸之至。

上一篇:flutter 保存网络图片至本地


下一篇:vue组件Better-Scroll基本用法