Dart异步编程--Future

Posted 未来如诗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dart异步编程--Future相关的知识,希望对你有一定的参考价值。

Dart是单线程编程语言, 如果Dart代码被阻塞了(比如一段耗时的计算代码或者等待I/O操作), 整个程序都会被冻结。

当你的程序因为需要等待某个操作结束时,异步操作可以让你的程序继续执行其他的任务, Dart是使用Future对象来表示异步操作的结果,要使用future,你可以使用async和await或者Future API。

  • 所有的Dart代码都是执行在一个单独的isolate的上下文中,这些isolote都是独立的,不会共享内存信息。当dart代码正在执行的过程中,不会有其他的dart代码在相同的isolate中执行。

  • 如果你想让多个模块的Dart代码同时执行,你可以让代码在不同的isolate中(Web app一般使用workers来取代isolates)同时执行,通常每一个isoloate都有它自己的执行环境和内存区域,,isolate之间的通信只能通过发送消息的方式来实现,具体的信息可以,查看文挡isolate或者Web workers。


介绍

下面看一段代码可能会导致程序被阻塞

Dart异步编程--Future

程序中需要去获取当天的新闻,并且打印出来,然后打印出用户感兴趣的新闻

Dart异步编程--Future

代码的问题是:gatherNewsReports()方法被block了,剩下的代码需要等gatherNewsReports()返回了新闻信息保存在文件中,无论这个方法耗时多长,如果读取这个文件消耗了很长的一段时间,用户必须等着去获取电量, 明天的天气和比赛结果。

为了保持程序可响应,可以把一下耗时的操作定义为异步操作,这些方法都是通过Future来返回结果。

What is future?

future是一个Futere<T>的一个泛型对象,表示一个异步操作的结果是T类型。如果这个结果不是可以直接使用,可以使用Future<void>。 当调用返回future的函数时,会发生2件事。

  • 函数队列开始执行,结束的时候返回一个Future对象.

  • 当这个操作结束的时候,这个Future对象会返回一个值或者error.

当需要依赖Future去编码时,可以有两个选择

  • 使用asyn和await

  • 使用Future的API

Async and await

async和await是Dart实现异步操作的两个关键词, 可以让你在实现异步的代码的时候看起来像同步的代码并且没有使用Future的api。异步的方法是在函数体之前添加上async就行。 await关键词只能作用于异步的方法。

Dart异步编程--Future

注意到printDailyNewsDigest()方法第一个被调用,但是新闻内容却是在最后一行被打印出来,即使是这个新闻文件中只包含了一行文字。这个因为这行代码中的reads和prints是异步的执行。

在这个例子中,printDailyNewsDigest()中调用了gatherNewsReports(),程序没有被阻塞。在调用gatherNewsReports()方法的时候,队列开始进行工作,同时并没有阻塞下面的代码继续执行,这个程序先打印出了点量,天气预报,比赛结果,当printDailyNewsDigest()方法获取新闻信息结束之后,开始打印。

下面这个图显示了这段代码的执行顺序

Dart异步编程--Future

  1. 程序开始执行

  2. main方式开始调用异步方法printDailyNewsDigest()。

  3. printDailyNewsDigest()使用await来调用gatherNewsReports(), 开始执行。

  4. gatherNewsReports()方法返回了一个未完成的future。

  5. 因为printDailyNewsDigest()是一个异步的方法,并且在等待一个返回值,暂停执行返回一个为完成的future给main函数。

  6. 剩下的print方法开始执行,因为它们是同步的,每一个方法都需要等它的上一个方法执行完成之后才能继续执行。例如获取电量在获取天气预报之前。

  7. 当main函数执行完成之后,异步方法可以重新开始执行。首先gatherNewsReports()方法返回的future完成了,printDailyNewsDigest()开始执行,打印结果。

  8. printDailyNewsDigest函数的方法体执行完成之后,之前返回的future执行完成,程序退出。

错误处理

如果一个future返回的是一个error, 程序可能需要去捕获这个error, 异步方法可以使用try-catch来捕获error.

Dart异步编程--Future

同步过程

可以使用await让代码同步的执行

expensiveB()方法在expensiveA()执行结束之前不会执行。

Future API

在Dart中添加async和await之前,必须使用Future API。 可能在老的代码中仍然使用了API, 以及在需要比异步等待提供更多功能的代码中使用API。

要使用Future API编写异步代码,可以使用then()方法注册回调,当future完成的时候就会触发这个回调。

参考文档

https://www.dartlang.org/tutorials/language/futures


以上是关于Dart异步编程--Future的主要内容,如果未能解决你的问题,请参考以下文章

异步编程之 Future

异步编程之 Future

Dart中的异步编程(Future、scheduleMicrotask)

Flutter之异步操作async原理Future本质

Flutter之异步操作async原理Future本质

Flutter之异步操作async原理Future本质