广告
返回顶部
首页 > 资讯 > 移动开发 >Flutter异步操作实现流程详解
  • 947
分享到

Flutter异步操作实现流程详解

2024-04-02 19:04:59 947人浏览 独家记忆
摘要

目录一、FutureBuilder二、StreamBuilder在Flutter中,借助 FutureBuilder 组件和 StreamBuilder 组件,可以非常方便地完成异步

Flutter中,借助 FutureBuilder 组件和 StreamBuilder 组件,可以非常方便地完成异步操作。

一、FutureBuilder

在讲解FutureBuilder之前,你首先要知道Future是什么,了解了这个,后面再了解该组件就轻松许多。

在不同的编程语言中会有不同的名词来定义,在dart语言中 选择使用Future类型配合async、await关键字来实现异步支持。

Future 表示一个现在不确定,但以后应该可以确定的值。这个值可以是任意类型,如 Future<int>表示一个未来获取到的整型值,Future<String>表示一个未来获取到的字符串

我们通常会在定时器、网络请求中使用Future,它会有三种状态:uncompleted(未完成)、completed with data(获取到一个数据)、completed with error(捕获到一个错误),所以在实战过程中,我们需要根据这三种状态来判断当前界面应该是怎样的,加载中、数据正常显示、提示错误 重新操作。

小示例:

定义一个getValue方法:

Future<String> getValue() async {
    await Future.delayed(Duration(seconds: 3));
    return "100";
}

结合FutureBuilder组件来调用方法:

FutureBuilder(
  future: getValue(),
   builder:
       (BuildContext context, AsyncSnapshot<String> snapshot) {
     if (snapshot.hasData) {
       return Text(
           "${snapshot.data}",
           style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
         );
     } else if (snapshot.hasError) {
       return Text("${snapshot.error}");
     } else {
       return Container(
         height: 50,
         width: 50,
         margin: EdgeInsets.only(top: 10),
         child: CircularProgressIndicator(
           strokeWidth: 8.0,
         )
       );
     }
   }),

我们逐步来分解上面的示例代码:

  1. 这里使用async关键字将函数标为异步函数,这样函数的返回值就会被封装为异步。
  2. FutureBuilder组件的future属性是此组件的必传参数。FutureBuilder组件得到future之后,便开始通过future的then等方法追踪它(监听future执行的结果),当其状态改变时自动调用builder函数重绘。
  3. builder函数。每次绘制时,FutureBuilder都会调用这里的builder回传函数,并提供BuildContext(上下文)和AsyncSnapshot<>(异步快照)。在这里AsyncSnapshot<> 封装的类型就是future参数里的Future<> 所封装的类型。像上例一样,Future返回一个String,那么对应的AsyncSnapshot也是String类型。
  4. AsyncSnapshot 中含有 Future的最新状态及被封装的数据或异常。另外ConnectionState 属性描述了 Future 的四种状态,其分别为 none、waiting、active、done。
  5. 大多数时间做异步操作都是为了获取最终的数据,那么这个数据的获取即是在Future的done(完成)之后,所以我们的逻辑代码可以这样写。
FutureBuilder(
   future: getValue(),
   builder:
       (BuildContext context, AsyncSnapshot<String> snapshot) {
     if(snapshot.connectionState == ConnectionState.done) {
       if (snapshot.hasData) {
         return Text(
           "${snapshot.data}",
           style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
         );
       } else {
         return Text("${snapshot.error}");
       }
     }else {
       return Container(
           height: 50,
           width: 50,
           margin: const EdgeInsets.only(top: 10),
           child: const CircularProgressIndicator(
             strokeWidth: 8.0,
           )
       );
     }
   }),

首先判断Future的状态是否完成,未完成的情况下就加载动画组件。加载完成的情况下再进行判断snapshot返回的是正确数据还是异常,此时data和error必有一个且只有一个不是空。

总结一下:在Future完成之前,data和error都为空,Future完成之后,data和error有且仅有一个为空。所以这个时候我们可以不检查Future的状态是否完成,而是直接通过snapshot的hasData数据和hasError异常来判断。如果既没有数据又没有异常,那就是当前的Future还未完成,可直接返回加载动画组件。这个时候的代码就如最开始的那个示例一样直接检查hasData和hasError。

初始值 initialData

在Future完成之前,initialData属性提供一个数据的初始值给FutureBuilder组件使用。在有初始值的情况下,Future完成之前hasData会返回true,并且data中存储着所设置的初始值。当Future完成之后,FutureBuilder组件会自动切换到Future的真实值并重新渲染。

FutureBuilder(
   future: getValue(),
   initialData: "加载中...",
   builder:
       (BuildContext context, AsyncSnapshot<String> snapshot) {
       if (snapshot.hasData) {
         return Text(
           "${snapshot.data}",
           style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
         );
       } else {
         return Text("${snapshot.error}");
       }
   }),

二、StreamBuilder

StreamBuilder组件与FutureBuilder组件相同之外的不同之处在于它是一个可以自动跟踪Stream的状态,并在Stream有变化时自动重绘的组件。

那么问题来了,什么是Stream?在这里,我们称之为数据流或事件流。Data Stream、Event Stream。

顾名思义,既然称之为“流”,那可以想象出这是一种不间断的操作。

我们可以通过使用Stream.periodic构造函数,并借助其count参数(当前Stream已被调用的次数,从0开始递增),制作一个一秒加一的计数器数据流。

方法:

Stream<int> counter() {
    return Stream.periodic(
      const Duration(seconds: 1),
      (count) => count
    );
  }

在组件中使用:

StreamBuilder(
    stream: counter(),
    builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
      switch(snapshot.connectionState) {
        case ConnectionState.none:
          return Text("无数据流");
        case ConnectionState.done:
          return Text("数据流关闭");
        case ConnectionState.waiting:
          return Text("等待数据");
        case ConnectionState.active:
          if(snapshot.hasData) {
            return Text("${snapshot.data}");
          }else {
            return Text("${snapshot.error}");
          }
        default:
          throw "connect error";
      }
    })

这种用法有点像js中的 setInterval() 一样。

StreamBuilder组件与FutureBuilder组件用法类似,只是在这里所传的参数不是future,而是stream,同时可以通过builder回传函数 获取Stream的4中状态,编写业务逻辑。用法与FutureBuilder组件中的状态类似,这里不过多重复。

上面这种普通数据流的写法只监听count()方法,如果需要支持多个监听者同时监听,则可以通过控制器的StreamController.broadcast构造函数创建一个广播数据流。实现界面多处位置监听并重绘StreamBuilder组件。

例如:

final _stream = StreamController<int>();
StreamBuilder(
    stream: _stream.stream.map((event) => "value:${event}"),
    builder: (context, snapshot) {
      if(snapshot.connectionState == ConnectionState.done) {
        return Text("close stream");
      }
      if(snapshot.hasData) return Text("${snapshot.data}");
      if(snapshot.hasError) return Text("${snapshot.error}");
      return CircularProgressIndicator();
  }),
  Row(
    children: [
      ElevatedButton(onPressed: () => _stream.add(666), child: Text("添加666")),
    	SizedBox(width: 20,),
     ElevatedButton(onPressed: () => _stream.add(888), child: Text("添加888")),
     SizedBox(width: 20,),
     ElevatedButton(onPressed: () => _stream.close(), child: Text("关闭数据流")),
    ],
  )

在最开始,Stream没有开始释放任何事件,这时StreamBuilder会先渲染一个加载组件,当点击第一个按钮,界面将会显示 value:666 字样。只要不关闭数据流,StreamBuilder就会一直监听,任何一处controller的变化。

到此这篇关于Flutter异步操作实现流程详解的文章就介绍到这了,更多相关Flutter异步操作内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Flutter异步操作实现流程详解

本文链接: https://www.lsjlt.com/news/168398.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Flutter异步操作实现流程详解
    目录一、FutureBuilder二、StreamBuilder在Flutter中,借助 FutureBuilder 组件和 StreamBuilder 组件,可以非常方便地完成异步...
    99+
    2022-11-13
  • Android Flutter异步编程怎么实现
    这篇文章主要介绍“Android Flutter异步编程怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android Flutter异步编程怎么实现”文章能帮助大家解决问...
    99+
    2023-07-05
  • FlutterFuture异步操作详细讲解
    目录异步future创建Future异步创建使用Futureawait关键字Streamstream和Future的区别生成器函数同步生成器异步生成器递归生成器异步 future F...
    99+
    2023-03-10
    Flutter Future异步操作 Flutter Future异步 Flutter异步操作
  • Flutter 异步编程之单线程下异步模型图文示例详解
    目录一、 本专栏图示概念规范1. 任务概念规范2. 任务的状态3. 时刻与时间线4.同步与异步二、理解单线程中的异步任务1. 任务的分配2.异步任务特点3. 异步任务完成与回调三、 ...
    99+
    2022-11-13
  • Java 异步编程 (5 种异步实现方式详解)
    同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现 @mikechen 目录 什么是异步?一、线程异步二、Future异步三、CompletableFuture异步四、Spring...
    99+
    2023-09-02
    java jvm 数据库
  • JavaScript异步编程操作实现介绍
    目录异步编程同步模式与异步模式同步模式(Synchronous)异步模式(Asynchronous)回调函数PromisePromise基本用法Promise使用案例Promise常...
    99+
    2022-11-13
  • Flutter+Metal实现图像处理详细流程
    背景 在之前自制的图像处理App中,使用了OpenGL处理图片,这次使用Metal替代OpenGL,来达到更好的性能,顺便熟悉一下Metal的渲染流程 基本思路 Flutter使用...
    99+
    2022-11-13
  • Java 的异步编程 (5 种异步实现方式详解)
    一、线程异步 创建一个异步线程 public class AsyncThread extends Thread{ @Override public void run() { System.out.println("...
    99+
    2023-09-03
    java jvm 开发语言
  • 详解JavaScript实现异步Ajax
    目录一、什么是 AJAX ?1、AJAX是基于现有的Internet标准2、AJAX 工作原理二、AJAX - 创建 XMLHttpRequest 对象1、XMLHttpReques...
    99+
    2022-11-13
  • 详解Spring DeferredResult异步操作使用场景
    目录为什么使用DeferredResult?场景Demo代码测试1. 超时2. 进行setResult总结:为什么使用DeferredResult? API接口需要在指定时间内将异步...
    99+
    2022-11-12
  • React 中 setState 的异步操作案例详解
    目录前言React 中的 setState 为什么需要异步操作?什么时候setState会进行同步操作?前言 在使用state的时候, 如果我们企图直接...
    99+
    2022-11-13
  • C#如何实现异步操作
    这篇文章给大家分享的是有关C#如何实现异步操作的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。.NET Framework 为异步操作提供了两种设计模式:使用 IAsyncResult 对象的异步操作与使用事件的异...
    99+
    2023-06-18
  • PHP怎么实现异步操作
    这篇文章主要讲解了“PHP怎么实现异步操作”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP怎么实现异步操作”吧!1.为啥PHP需要异步操作?一般来说PHP适用的场合是web页面展示等耗时...
    99+
    2023-06-04
  • javaCompletableFuture实现异步编排详解
    目录前言CompletableFuture的使用① 创建CompletableFuture的方式② 获得异步执行结果③ 对执行结果进行处理④ 对执行结果进行消费⑤ 异常处理⑥ 两组任...
    99+
    2023-01-30
    java CompletableFuture异步编排 java CompletableFuture
  • ADO.NET中怎么实现异步操作
    ADO.NET中怎么实现异步操作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。线程是允许程序的一部分独立于其他部分运行。线程可以在单个线程执行的同时运行多个操作,让用户感到像同...
    99+
    2023-06-17
  • C#中怎么实现异步操作
    C#中怎么实现异步操作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。//首先准备好,要进行异步的方法(能异步的,***不多线程)  private ...
    99+
    2023-06-17
  • C++中怎么实现异步操作
    C++中怎么实现异步操作,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。实现(代码)#include <iostream> #include&nb...
    99+
    2023-06-17
  • JavaScript实现Promise流程详解
    目录构造函数then 和 catch方法解决异步问题all和race方法构造函数 首先我们来看一下我们是如何使用promise的,我们在实例化对象是这么使用的: let p1...
    99+
    2022-11-13
  • Python实现JavaBeans流程详解
    目录场景JavaBeans in Python在JavaBeans中有这样的一个描述:当一些信息需要使用类似于字典嵌套字典再嵌套列表这种很深的结构来储存的时候,请改用类来储存。实际上...
    99+
    2023-01-14
    Python JavaBeans Python实现JavaBeans
  • php操作ElasticSearch搜索引擎流程详解
    目录一、安装二、使用三、新建ES数据库四、创建表五、插入数据六、 查询所有数据七、查询单条数据八、搜索九、测试代码〝 古人学问遗无力,少壮功夫老始成 〞 如果这篇文章能给你带来一点帮助,希望给飞兔小哥哥一键三连,表示支持,谢谢各位小伙伴们。...
    99+
    2021-02-18
    php ElasticSearch搜索引擎 php 搜索引擎
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作