void syncDemo1() {
Future(() => print(“print future1”));//a
print(“print 1”);//b
Future(() => print(“print 2”))//c
…then((value) => print(“print 3”))//d
…then((value) => print(“print 4”));//e
}
print 1
print future1
print 2
print 3
print 4
调用的顺序是:
- a 添加到任务队列;
- b 在主线程,执行执行;
- c 添加到任务队列;这时候在主线程没有任务了,从任务队列取出 a,并执行
- 执行a 后,主线程没有任务,还是从任务队列取出c 执行,then 后面的函数会依次同步执行;
异步函数
对于一个异步函数来说,其返回时内部执行动作并未结束,因此需要返回一个 Future 对象,供调用者使用。调用者根据 Future 对象,来决定:
- 是在这个 Future 对象上注册一个 then,等 Future 的执行体结束了以后再进行异步处理;
- 还是一直同步等待 Future 执行体结束。对于异步函数返回的 Future 对象,如果调用者决定同步等待,则需要在调用处使用 await 关键字,并且在调用处的函数体使用 async 关键字。
void syncFunDemo() async{
Future future() => Future.delayed(Duration(seconds: 3),()=>“hello 2021”);
// future.then((value) => print(“获取到异步数据$value”));//等待完成后,执行then里面的函数
print(“获取到异步数据”+ (await future()));//同步等待
}
为什么要加上 async?
因为 Dart 中的 await 并不是阻塞等待,而是异步等待。Dart 会将调用体的函数也视作异步函数,将等待语句的上下文放入 Event Queue 中,一旦有了结果,Event Loop 就会把它从 Event Queue 中取出,等待代码继续执行。
Flutter 中的网络请求
在了解了异步操作之后,趁热打铁,学习flutter 中的网络请求。
网络与服务端数据交互时,不可避免地需要用到三个概念:定位、传输与应用。
其中,定位,定义了如何准确地找到网络上的一台或者多台主机(即 IP 地址);传输,则主要负责在找到主机后如何高效且可靠地进行数据通信(即 TCP、UDP 协议);而应用,则负责识别双方通信的内容(即 HTTP 协议)。
一般的网络请求框架中,依次http 网络调用 可以分为以下几个部分:
- 创建网络调用实例 client,设置通用请求行为(如超时时间);
- 构造 URI,设置请求 header、body;
- 发起请求, 等待响应;
- 解码响应的内容。
在 Flutter 中,Http 网络编程的实现方式主要分为三种:dart:io 里的 HttpClient 实现、Dart 原生 http 请求库实现、第三方库 dio 实现。