内容简介:构造函数很简单,上一篇文章也说过,主要就是三个参数:其中其中
const FutureBuilder({ Key key, this.future, this.initialData, @required this.builder, }) : assert(builder != null), super(key: key); 复制代码
构造函数很简单,上一篇文章也说过,主要就是三个参数:
- future:是我们的异步请求, 该异步请求必须不能在 build 方法中初始化!
- initialData:如果Future 没有完成的情况下展示该数据
- builder:构建我们的UI
AsyncWidgetBuilder
其中 builder
的类型为 AsyncWidgetBuilder
,我们来看一下:
typedef AsyncWidgetBuilder<T> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot); 复制代码
其中 typedef
是为函数起别名用的,
也就是说 builder 是一个方法,从而在定义builder的时候就要实现这个方法。
AsyncSnapshot
接着看一下 snapshot
:
@immutable class AsyncSnapshot<T> { /// Creates an [AsyncSnapshot] with the specified [connectionState], /// and optionally either [data] or [error] (but not both). const AsyncSnapshot._(this.connectionState, this.data, this.error) : assert(connectionState != null), assert(!(data != null && error != null)); /// Creates an [AsyncSnapshot] in [ConnectionState.none] with null data and error. const AsyncSnapshot.nothing() : this._(ConnectionState.none, null, null); /// Creates an [AsyncSnapshot] in the specified [state] and with the specified [data]. const AsyncSnapshot.withData(ConnectionState state, T data) : this._(state, data, null); /// Creates an [AsyncSnapshot] in the specified [state] and with the specified [error]. const AsyncSnapshot.withError(ConnectionState state, Object error) : this._(state, null, error); /// Current state of connection to the asynchronous computation. final ConnectionState connectionState; /// The latest data received by the asynchronous computation. /// /// If this is non-null, [hasData] will be true. /// /// If [error] is not null, this will be null. See [hasError]. /// /// If the asynchronous computation has never returned a value, this may be /// set to an initial data value specified by the relevant widget. See /// [FutureBuilder.initialData] and [StreamBuilder.initialData]. final T data; /// Returns latest data received, failing if there is no data. /// /// Throws [error], if [hasError]. Throws [StateError], if neither [hasData] /// nor [hasError]. T get requireData { if (hasData) return data; if (hasError) throw error; throw StateError('Snapshot has neither data nor error'); } /// The latest error object received by the asynchronous computation. /// /// If this is non-null, [hasError] will be true. /// /// If [data] is not null, this will be null. final Object error; /// Returns a snapshot like this one, but in the specified [state]. /// /// The [data] and [error] fields persist unmodified, even if the new state is /// [ConnectionState.none]. AsyncSnapshot<T> inState(ConnectionState state) => AsyncSnapshot<T>._(state, data, error); /// Returns whether this snapshot contains a non-null [data] value. /// /// This can be false even when the asynchronous computation has completed /// successfully, if the computation did not return a non-null value. For /// example, a [Future<void>] will complete with the null value even if it /// completes successfully. bool get hasData => data != null; /// Returns whether this snapshot contains a non-null [error] value. /// /// This is always true if the asynchronous computation's last result was /// failure. bool get hasError => error != null; } 复制代码
前面定义了一个私有的构造函数 const AsyncSnapshot._(this.connectionState, this.data, this.error)
,
后面 用命名构造函数来调用私有构造函数 返回一个 snapshot。
也可以看到 hasData
hasError
其实就是判断 data/error 是否等于 null。
_FutureBuilderState
重点是 _FutureBuilderState<T>
,还是从上往下看,
首先定义了两个私有变量:
/// An object that identifies the currently active callbacks. Used to avoid /// calling setState from stale callbacks, e.g. after disposal of this state, /// or after widget reconfiguration to a new Future. Object _activeCallbackIdentity; AsyncSnapshot<T> _snapshot; 复制代码
_activeCallbackIdentity
根据注释来解释大概就是: 标记当前还存活的对象,用于避免已经dispose了还调用setState。
_snapshot
就是我们刚才说用来返回数据的。
initState()
接着是初始化方法:
@override void initState() { super.initState(); _snapshot = AsyncSnapshot<T>.withData(ConnectionState.none, widget.initialData); _subscribe(); } 复制代码
首先根据传入的 initialData
初始化_snapshot,
然后调用 _subscribe()
_subscribe()
看一下 _subscribe()
方法 :
void _subscribe() { if (widget.future != null) { final Object callbackIdentity = Object(); _activeCallbackIdentity = callbackIdentity; widget.future.then<void>((T data) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = AsyncSnapshot<T>.withData(ConnectionState.done, data); }); } }, onError: (Object error) { if (_activeCallbackIdentity == callbackIdentity) { setState(() { _snapshot = AsyncSnapshot<T>.withError(ConnectionState.done, error); }); } }); _snapshot = _snapshot.inState(ConnectionState.waiting); } } 复制代码
这里做了如下几件事:
-
判断 future 是否为null;
-
如果不为null,则初始化
_activeCallbackIdentity
为 Object(); -
变更 _snapshot 的状态为
ConnectionState.waiting
; -
接着对 Future 调用 then 方法,这里主要就是先判断了
callbackIdentity
是否相等,如果不相等,那么这个 Future肯定是更改了,或者已经 dispose 了。如果callbackIdentity
相等, 则继续判断是有错误还是有数据 ,有数据就调用AsyncSnapshot<T>.withData
,有错误就调用AsyncSnapshot<T>.withError
,并传入状态。
didUpdateWidget
接着下面是 didUpdateWidget
方法,该方法主要是用来判断是否需要更新 widget:
@override void didUpdateWidget(FutureBuilder<T> oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.future != widget.future) { if (_activeCallbackIdentity != null) { _unsubscribe(); _snapshot = _snapshot.inState(ConnectionState.none); } _subscribe(); } } 复制代码
这里更新的逻辑是判断 future 是否一样,如果不一样则:
_activeCallbackIdentity _activeCallbackIdentity = null; ConnectionState.none
dispose()
最后就是 dispose()
方法:
@override void dispose() { _unsubscribe(); super.dispose(); } 复制代码
FutureBuilder 重写该方法来达到 dispose
时自动取消订阅。
总结
Future 的状态无非三种:
- 未开始
- 进行中
- 已完成
其中 已完成 又分为两种:
- 有数据
- 有异常
其实可以看到,FutureBuilder 大体上的思路就是对 Future 状态的封装,从而达到我们想要的效果。
在 Flutter 中,我们可以通过查看源码来获取很多的灵感,因为 Flutter 的 注释写的简直不要太到位 !
以上所述就是小编给大家介绍的《FutureBuilder源码分析》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 以太坊源码分析(36)ethdb源码分析
- [源码分析] kubelet源码分析(一)之 NewKubeletCommand
- libmodbus源码分析(3)从机(服务端)功能源码分析
- [源码分析] nfs-client-provisioner源码分析
- [源码分析] kubelet源码分析(三)之 Pod的创建
- Spring事务源码分析专题(一)JdbcTemplate使用及源码分析
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mastering JavaServer Faces
Bill Dudney、Jonathan Lehr、Bill Willis、LeRoy Mattingly / Wiley / 2004-6-7 / USD 40.00
Harness the power of JavaServer Faces to create your own server-side user interfaces for the Web This innovative book arms you with the tools to utilize JavaServer Faces (JSF), a new standard that wi......一起来看看 《Mastering JavaServer Faces》 这本书的介绍吧!