美文网首页Flutter圈子Flutter
跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ios

跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ios

作者: 王二蛋和他的狗 | 来源:发表于2022-03-30 10:48 被阅读0次

前言

Dart是单线程的,Dart提供了Isolate,isolate提供了多线程的能力。但作为多线程能力的,却内存不能共享。但同样的内存不能共享,那么就不存在锁竞争问题。

举个例子来展示作用

如果一段代码执行事件很长,flutter如何开发。
基本页面代码(一段代码)

ElevatedButton(
              child: Text("登录"),
              onPressed: () {
                执行运行代码();
              }

延时代码块

String work(int value){
  print("work start");
  sleep(Duration(seconds:value));
  print("work end");
  return "work complete:$value";
}

第一种:直接执行运行代码(延时5秒)

  执行运行代码() {
    work(5);
  }

结果:
5秒卡的死死的

第二种:async执行运行代码(延时5秒)

  执行运行代码() async{
    work(5);
  }

结果:
5秒依旧卡的死死的

------------------------------------------------我是分割线--------------------------------------------------

why?在dart中,async不是异步计算么?(循环机制下篇讲)因为我们仍旧是在同一个UI线程中做运算,异步只是说我可以先运行其他的,等我这边有结果再返回,但是,我们的计算仍旧是在这个UI线程,仍会阻塞UI的刷新,异步只是在同一个线程的并发操作。

第三种:ioslate执行运行代码(延时5秒)

但是由于dart中的Isolate比较重量级,UI线程和Isolate中的数据的传输比较复杂,因此flutter为了简化用户代码,在foundation库中封装了一个轻量级compute操作。

  执行运行代码() async{
    var result = await compute(work, 5);
    print(result);
  }

结果:
居然不卡顿了

使用说明

compute的使用还是有些限制,它没有办法多次返回结果,也没有办法持续性的传值计算,每次调用,相当于新建一个隔离,如果调用过多的话反而会适得其反。我们需要根据不同的业务选择用compute和isolate


Future<dynamic> work(int value) async{
  //接收消息管道
  ReceivePort rp = new ReceivePort();
  //发送消息管道
  SendPort port = rp.sendPort;
  Isolate isolate = await Isolate.spawn(workEvent, port);
  //发送消息管道2
  final sendPort2 = await rp.first;
  //返回应答数据
  final answer = ReceivePort();
  sendPort2.send([answer.sendPort, value]);
  return answer.first;
}

void workEvent(SendPort port) {
  //接收消息管道2
  final rPort = ReceivePort();
  SendPort port2 = rPort.sendPort;
// 将新isolate中创建的SendPort发送到主isolate中用于通信
  port.send(port2);

  rPort.listen((message) {
    final send = message[0] as SendPort;
    send.send(work(5));
  });
}

基本方法

    //恢复 isolate 的使用
    isolate.resume(isolate.pauseCapability);

    //暂停 isolate 的使用
    isolate.pause(isolate.pauseCapability);

    //结束 isolate 的使用
    isolate.kill(priority: Isolate.immediate);

    //赋值为空 便于内存及时回收
    isolate = null;

两个进程都双向绑定了消息通信的通道,即使新的Isolate中的任务完成了,它的进程也不会立刻退出,因此,当使用完自己创建的Isolate后,最好调用isolate.kill(priority: Isolate.immediate);将Isolate立即杀死。

用Future还是isolate?

future使用场景:

  • 代码段可以独立运行而不会影响应用程序的流畅性

isolate使用场景:

  • 繁重的处理可能要花一些时间才能完成
  • 网络加载大图
  • 图片处理

相关文章

网友评论

    本文标题:跟我学flutter:我们来举个例子通俗易懂讲解异步(一)ios

    本文链接:https://www.haomeiwen.com/subject/sxvijrtx.html