源码解读:Flutter异步刷新UI相关概念

本文从源码角度去阐述并记录笔者学习Flutter异步刷新UI的相关知识点,读完本篇能大体了解一下知识点:Future、Stream、StreamBuilder、Provider&MultiProvider是什么?解决了什么问题?如何用?
Future和Stream是异步事件的数据资源提供者,后两者则是对异步数据进行同步处理的加工者。

  • Future
    1.是什么?
    Future和它的名字一样,代表在未来一段时间内可能会代表某类事物,所以说代表着异步操作返回解决,具体代表什么结果呢?有两种可能的结果一种是你异步正常completed之后的正常数据他的类型有两种Feature和T,T在这里代表泛型,也可能是完成过程中报错返回的error数据。
    2.主要解决了什么?
    避免在UI主线程做耗时操作,同时在异步线程完成操作后将结果返回到UI主线程做同步非耗时操作,简而言之,避免耗时操作阻塞UI主线程。
    3.如何用?
    最常用的用法是和async和await连用,作为async方法的返回值。
简单用法:
 Future getFuture() async{
    return 1;
  }
Future<int> future = getFuture();//源码提供了很多实例化一个Future的方法,选个合适创建Future对象
      future.then((value) => handleValue(value))
           .catchError((error) => handleError(error));
 类比操作:
 // Synchronous code.
  try {
    int value = foo();
    return bar(value);
  } catch (e) {
    return 499;
  }
 // Equivalent asynchronous code, based on futures:
 Future<int> future = new Future(foo);  // Result of foo() as a future.
  future.then((int value) => bar(value))
       .catchError((e) => 499);

关于一些使用细节,这位老兄总结的很到位了,我就不造轮子了:https://juejin.im/post/5d317e5af265da1b6c5faf73

  • Stream
    1.是什么?
    一种异步数据时间的资源(机制),和Future一样每个数据时间会触发正确的应答和错误的应答。提供两种方式监听数据事件引发的变化:单订阅:生命周期中只允许一个listener做监听操作,上一个订阅取消可以接纳另外的一个listener监听,广播监听流:同一生命周期允许多个listener,单订阅流可以通过asBroadcastStream转成广播流。
    2.主要解决了什么?
    类似Future都是异步处理数据的一种机制。
    3.如何用?
    和Future一样提供了n多创建方法,也是按需使用,不过我们移动端使用的通常都是StreamBuilder,这里只列举其中一种常见方式,具体全部用法另一位老兄也已经写清楚了:https://juejin.im/post/5d3a91d1e51d457778117479
void _stream() async {
    Duration interval = Duration(seconds: 1);
    Stream<int> stream = Stream.periodic(interval, (data) => data);
    stream = stream.take(10);
    stream.listen((data) {
      print(data);
    }, onError: (error) {
      print("流发生错误");
    }, onDone: () {
      print("流已完成");
    }, cancelOnError: false);
  }

  • StreamBuilder
    1.是什么?
    是一个StatefulWidget的子类
    2.主要解决了什么?
    优化setState全局刷新element tree的做法,局部更新仅发生变化的部分。类比FutureBuilder他们都是AsyncWidgetBuilder的代理类,他们的生命周期状态都是一指的,只不过变化的数据源的数据类型不同而已。FutureBuilder可以装换成StreamBuilder
    3.如何用?
从构造函数入手:
const StreamBuilder({
    Key key, //作为widget的key
    this.initialData, // 数据stream变化前的初始值
    Stream<T> stream, //数据流
    @required this.builder, //不能为null的widget builder
  }) : assert(builder != null),
       super(key: key, stream: stream);
       
 const FutureBuilder({
    Key key,
    this.future,
    this.initialData,
    @required this.builder,
  }) : assert(builder != null),
       super(key: key);
  • Provider&MultiProvider
    1.是什么?
    和StreamBuilder一样也是可以异步操作数据,同步更新局部UI工具包,字面意思更像生产者和消费者的处理方式反正都是订阅回调那一套。
    2.主要解决了什么?
    按照官方的说法是解决了全局widget state的滥用,代码更有条理且更高效。
    3.如何用?
    经验使得:同一个widget内部用StreamBuilder能省点代码且简洁,牵扯到多个widget的互动用Provider效果更好。
    1)引入provider包
    2)with 实现ChangeNotifier将数据model变成可被监听的provider
    3)用ChangeNotifierProvider宣布你在布局中需要监听的element tree范围,推荐用Consumer处理监听到的数据变化。两者都需要言明要监听的ChangeNotifier实例是什么。
    这位老兄写的是最简洁易懂的:https://juejin.im/post/5cdee8a151882525b21a5f9e

总结:本篇总体上是在摸鱼,因为已经有大佬把相关内容写的比较通俗易用了,但是上手又是另一回事了多多练习吧。

你可能感兴趣的:(Flutter)