美文网首页Flutter圈子
Flutter总结 - Dart异步

Flutter总结 - Dart异步

作者: HelloLeol | 来源:发表于2020-04-07 00:44 被阅读0次

搭完博客开始对flutter进行简单的总结
跳过一些基础的使用方法,主要对涉及使用到但是不清楚的部分学习归纳

Future async await

异步是开发过程躲不开的一个问题(处理网络又不能忽略前台响应),这次先介绍dart里面以下几个关键词:

Future:一种class类型,表示一种不会立即完成的计算过程。
async:关键字 用来修饰方法表示该方法异步,存在耗时的时候使用。
await:异步转同步,会等到该方法执行完成后再继续执行。

首先dart其实并不存在多线程,采取类似JS的事件方式实现异步,具体后面总结。
官网在介绍这一张时给出了一个很好的例子

String createOrderMessage () {
  var order = fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() {
  // Imagine that this function is more complex and slow
  return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}

void main () {
  print(createOrderMessage());
}

运行后会出现异常,动态类型出错,第三行的order是Future<String> 不是String不能直接打印。
如果需要异步转同步那么就需要像下面一样使用提到的关键字。

Future<String> fetchUserOrder() {
  // Imagine that this function is more complex and slow.
  return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}

Future<void>main() async{
  print('Awaiting user order...');
  var order = await fetchUserOrder();
  print('Your order is: $order');
}

在使用的地方用await修饰Future,并且用async修饰方法,才可以实现异步转同步。
即例子中成功获得用户思考4秒后给出的点单类型。
但是要注意下面几个基本问题:

如果只有await没有async会直接报错。
如果有async没有await不会报错,但是异步不会转为同步。
如果有await修饰的返回值不是Future也不会有任何效果。

String fetchUserOrder() {
  countSeconds(4);
  return "xxx";
}

Future<void>main() async{
  print('Awaiting user order...');
  var order = await fetchUserOrder();
  print('Your order is: $order');
}

void countSeconds(s) {
  for( var i = 1 ; i <= s; i++ ) {
      Future.delayed(Duration(seconds: i), () => print(i));
   }
}

比如上面这个例子,使用await修饰的函数返回的是String,但下面一行并不会等到记数之后执行。

Future的更多用法

上面的例子是一种最基本的用法,在网络访问中,按上面的结构会嵌套很深。Dart为网络场景(当然也不光只有网络访问可以使用),提供了一套类似于Promise的链式调用方法。见注释。

Future<String> fetchUserOrder() {
  // Imagine that this function is more complex and slow
  return Future
    .delayed(Duration(seconds: 4), () => 'Large Latte')
    .then((value) => value) // 对值进行处理
    .catchError(() => print('catch error')) // 捕获异常
    .whenComplete(() => print('completed'));// 类似于final
}

延伸

从上面可以看到每次都是用Future.delayed开启一个“新的线程”,但是上面不是又说了dart是单线程语言?

首先,dart并无传统的线程概念,取而代之的是isolate。每一个isolate之间不共享内存,单独运行。官方给出的解释是:

在应用运行中UI创建回收过程十分频繁,隔离设计可以方便快速进行垃圾管理。

isolate以后进行介绍,那么Future是不是开了一个isolate来进行异步? 也不是。具体实现如下

1⃣️当主isolate通过进行初始化运行之后,会立刻建立两个队列MicroTask QueueEvent Queue

2⃣️运行main函数,触发完成后进行下一步。

3⃣️运行Event Loop

[站外图片上传中...(image-9db77f-1586191438831)]

有点像加强版的Android Handler,不同的是拥有了两个队列往loop里面传递事件。

MicroTask:一些不耗时快速完成的任务,可以使用scheduleMicroTask()直接向队列里面传入任务。
Event:执行一些较耗时的任务,在MicroTask为空时,会从Event里面读取任务进行运行。Future实现异步也是依靠这个队列。

参考资料:
https://web.archive.org/web/20170704074724/https://webdev.dartlang.org/articles/performance/event-loop
https://medium.com/dartlang/dart-asynchronous-programming-isolates-and-event-loops-bffc3e296a6a
https://medium.com/@devexps/flutter-execute-code-with-microtask-queue-and-event-queue-f2dc10b06aad
https://dart.cn/codelabs/async-await

相关文章

  • 2019-09-23: 十一:Flutter之Dart异步操作?

    十一:Flutter之Dart异步操作? 1: Dart 的异步模型?我们先搞清楚dart是如何搞定异步操作的?1...

  • Flutter总结 - Dart异步

    搭完博客开始对flutter进行简单的总结跳过一些基础的使用方法,主要对涉及使用到但是不清楚的部分学习归纳 Fut...

  • @@@@@@@@

    \009-享学课堂安卓架构第一期├01 flutter│ ├Dart异步编程(1)-.mp4│ ├Dart异步...

  • 深入理解Flutter/Dart事件机制

    前言 在前文《Flutter/Dart中的异步》[https://juejin.cn/post/684490376...

  • FutureBuilder

    Flutter和Dart是异步的,使用Dart的Futures可以管理IO,不用担心线程死锁等问题,但是如何在使用...

  • flutter之---Future的正确用法

    在flutter中经常会用到异步任务,dart中异步任务异步处理是用Future来处理,那么如何实现用Future...

  • flutter Future

    在flutter中经常会用到异步任务,dart中异步任务异步处理是用Future来处理,那么如何实现用Future...

  • flutter

    1.dart2.flutter 本身3.项目中实际问题 dart 4个常用库:core:async异步编程通常使用...

  • Flutter开发之Dart语法基础(三)

    概览一、Dart的异步模型二、Dart的异步操作三、Dart的异步补充 一、Dart的异步模型 1.1 Dart是...

  • Day04-Dart-基础语法三:异步

    概述 Dart的异步模型 Dart的异步操作 Dart的异步补充 一、Dart的异步模型 1.1、Dart是单线程...

网友评论

    本文标题:Flutter总结 - Dart异步

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