dart系列之:dart中的异步编程

摘要:
在dart中,Future表示异步执行的结果。以下是两个不同返回的示例:Future<String>fetchUserOrder(){returnFuture.delay;}Future<void>fetchUser Order()}returnFuture.dedelay;}以下是异常的示例:,您可以直接使用trycatch来捕获异常:try{print;varorder=awaitfetchUserOrder();}catch{print;}在同步函数的异步函数中调用上述fetchUserOrder()以返回Future,表示异步执行过程。总之,这是DART中异步和等待的用法。

目录

简介

熟悉javascript的朋友应该知道,在ES6中引入了await和async的语法,可以方便的进行异步编程,从而摆脱了回调地狱。dart作为一种新生的语言,没有理由不继承这种优秀的品质。很自然的,dart中也有await和async语言,一起来看看吧。

为什么要用异步编程

那么为什么要用异步编程呢? 只用同步不能够解决吗?

其实大多情况下同步已经够用了,但是在下面的几种情况下,同步的场景还是有缺陷的。

  1. 需要花很长时间从网络上下载数据的情况。
  2. 读取数据库的耗时情况。
  3. 从文件读取数据的情况。

总结而言,如果某些操作需要花费大量的时间,那么就可以用到异步编程了。

怎么使用

async是方法的描述符,如果要使用await,则必须配合async一起使用:

Future<void> checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

注意,await后面一般接着的是Future对象。

先看一个错误使用异步编程的例子:


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

Future<String> fetchUserOrder() =>
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Order one!',
    );

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

上面的代码本意是打印出从数据库耗时取出的数据,但是结果并不是想象的那样,其原因就是fetchUserOrder方法是一个异步方法,所以不会立即返回,从而导致结果打印失败。

将上面的代码用async改写:

Future<String> createOrderMessage() async {
  var order = await fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() =>
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

Future<void> main() async {
  print('Fetching user order...');
  print(await createOrderMessage());
}
Future

上面我们在使用async和await的过程中使用到了Future。在java中Future表示的是线程的执行结果。在dart中Future表示的是一个异步执行的结果。

Future有两种状态:uncompleted 或者 completed。

当最开始执行一个异步函数的时候,会返回一个未完成的Future。这个未完成的Future会等等异步执行的完成或者失败。

不管异步程序是成功还是失败,最终都会返回一个完成状态。

async返回的Future可以接泛型,表示的时候返回的具体类型,比如Future 表示的是返回一个字符串,而 Future表示不返回任何值。

下面是两个不同返回的例子:

Future<String> fetchUserOrder() {
  return Future.delayed(const Duration(seconds: 2), () => 'Large Latte');
}

Future<void> fetchUserOrder() {
  return Future.delayed(const Duration(seconds: 2), () => print('Large Latte'));
}

下面是一个异常的例子:

Future<void> fetchUserOrder() {
  return Future.delayed(const Duration(seconds: 2),
      () => throw Exception('Logout failed: user ID is invalid'));
}
异步异常处理

在async的函数中,对await的异步方法中抛出的异常,可以直接是用try catch来进行异常的捕获:

try {
  print('Awaiting user order...');
  var order = await fetchUserOrder();
} catch (err) {
  print('Caught error: $err');
}
在同步函数中调用异步函数

上面介绍的fetchUserOrder()返回的是一个Future,表示的是一个异步执行的过程。

那么如果是一个同步的方法,比如main()函数中,如何去调用异步方法,并且得到返回值呢?

await肯定是不行的,因为await只能在async的方法中调用。这个时候就可以用到then语句:

fetchUserOrder().then(order=>'do something');

then语句会等待异步执行返回结果,然后对结果进行处理,实际上就等同于javascript中的回调。

总结

以上就是dart中async和await的用法。

本文已收录于 http://www.flydean.com/12-dart-async/

最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

免责声明:文章转载自《dart系列之:dart中的异步编程》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇web(五)---spawn-fastcgi[PostgreSQL] 图解安装 PostgreSQL下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C# HTTP请求 异步(async await)

static void Main(string[] args) { new Task(() => { Invoke(); }).Start(); Console.WriteLine("我是主线...

springboot(十九)-线程池的使用

我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行。 话不多说,编码开始: 1.创建springboot工程 创建一个springboot的web工程threadpooldemoserver,pom.xml内容如下: <project xmln...

jQuery同步Ajax带来的UI线程阻塞问题及解决办法

俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下。   事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return。基本的逻辑剥离出来是这样的: function get...

javascript ES6 新特性之 Promise,ES7 async / await

es6 一经推出,Promise 就一直被大家所关注。那么,为什么 Promise 会被大家这样关注呢?答案很简单,Promise 优化了回调函数的用法,让原本需要纵向一层一层嵌套的回调函数实现了横向的调用,也就是链式调用。 我们先来看下面的代码: 1 function getData(){ 2 setTimeout(()=>{ 3...

asp.net core 系列 5 项目实战之:NetCore 的 async 和 await(参考自:Microsoft教程)

十年河东,十年河西,莫欺少年穷 学无止境,精益求精 1、简介 从 VS 2012 开始,新引入了一个简化的方法,称为异步编程。我们在 >= .NETFRM 4.5 中和 Windows 运行时中使用异步,编译器它会帮助了我们降低了曾经进行的高难度异步代码编写的工作,但逻辑结构却类似于同步代码。因此,我们仅需要进行一小部分编程的工作就可以获得异步编程的...

使用 async-await 简化代码的检讨

  从API版本升级到4.6之后, Unity支持了async和await语法, 并且根据测试来看, 它运行在主线程里, 跟一般的C#编译不大一样, 这就很有操作空间了, 先来看看普通C# Console工程和Unity中运行的差别:   1. C# Console using System; namespace AsyncTest { clas...