异步:Future与FutureBuilder实用技巧

一、

 

二、什么是Future?

Future表示在接下来的某个时间的值或错误,借助Future我们可以在Flutter实现异步操作

Future是dart:async包中的一个类,使用它时需要导入dart:async包,Future有两种状态:

-pending -执行中;、

-completed-执行结束,分两种情况要么成功要么失败

注:它类似于ES6中的Promise,提供then和catchError的链式调用;

 

三、Future的常见用法?

-使用future.then获取future的值与捕获future的异常

-结合async,await

-future.whenComplete

-future.timeout

1、使用future.then获取future的值与捕获future的异常

调用Future.value()就是返回Future成功

调用Future.then()方法时,发生错误会回调onError()函数,同时也可以通过catchError()链式调用来捕获error异常。

如果同时调用了onError()和catchError(),发生错误的时候会优先调用onError(),如果onError()没有的话会优先调用catchError()

 

 

 

2、Future是异步的,如果我们要将异步转同步,那么可以借助aasync await来完成

3、future.whenComplete

有时候我们需要在Future结束的时候做些事情,我们知道then().catchError()的模式类似于try-catch,try-catch有个finally代码块,而future.whenComplete就是Future的finally。

4、future.timeout

完成一个异步操作可能需要很长的时间,比如:网络请求,但有时我们需要为异步操作设置一个超时时间,那么,如何为Future设置超时时间呢?

 

四、什么是FutureBuilder?

1、FutureBuildere是一个将异步操作和异步UI更新结合在一起的类,通过它我们可以将网络请求,数据库读取等的结果更新到页面上。

2、FutureBuilder的构造方法

FutureBuilder({Key key,Future<T> future,T initialData,@required AsyncWidgetBuilder<T>builder})

-future:Future对象表示此构造器当前连接的异步计算

-initialData:表示一个非空的Future完成前的初始化数据

-builder:AsyncWidgetBuilder类型返回的函数,是一个基于异步交互构建widget的函数

 

这个builder函数接收两个参数BuildContext context与AsyncSnapshot<T>snapshot,它返回一个widget。AsyncSnapshot包含异步计算的信息,它具有以下属性:

connectionState-枚举ConnectionState的值,表示与异步计算的连接状态,ConnectionState有四个值:none,waiting,active和done;data-异步计算接收的最新数据;error-异步计算接收的最新错误对象;

AsyncSnapshot还具有hasData和hasError属性,以分别检查它是否包含非空数据值或错误值。

使用FutureBuilder的基本模式,在创建FutureBuilder对象时,将Future对象作为要处理的异步计算传递。在构造器函数中,我们检查connectionState的值,并使用AsyncSnapshot中的数据或返回不同的窗口小部件。

 

2、FutureBuilder的使用?

 

3、使用FutureBuilder发送请求

但是运行到ConnectionState.none分支,原因是少配置了一个参数,没有配置future

 

4、添加future参数后可以正常发送请求并返回数据

 

5、返回的中文发生乱码

通过Utf8Decoder进行解码

 

 

 

 

五、使用步骤

1、在body这里,FutureBuilder是作为widget进行使用的

2、futureBuilder返回的泛型是CommonModel

3、FutureBuilder接收一个future参数,这个future参数调用了之前封装的fetchPost()函数

4、FutureBuilder里设置了一个builder参数,这个参数里接收两个参数:BuildContext context、AsyncSnapshot <CommonModel>snapshot,然后通过判断snapshot.connectionState的连接状态,来显示不同的状态