什么是Future?

Future表示在接下来的某个时间的错误,借助Future我们可以在Flutter实现异步操作。它类似于ES6中的Promise,提供then和catchError的链式调用。

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

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

Future的常见用法?

  • 使用future.then获取future的值与捕获future的异常
  • 结合async,await
  • future.whenComplete
  • future.timeout

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

import 'dart:async';
Future<String> testFuture() {
// throw new Error();
return Future.value('success');
// return Future.error('error');
} main() {
testFuture().then((s) {
print(s);
}, onError: (e) {
print('onError:');
print(e);
}).catchError((e) {
print('catchError:');
print(e);
});
}

Future的then的原型:

Future<R> then<R>(FutureOr<R> onValue(T value), {Function onError});

第一个参数会成功的结果回调,第二个参数onError可选表示执行出现异常。

结合async await

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

import 'dart:async';

test() async {
int result = await Future.delayed(Duration(milliseconds: ), () {
return Future.value();
});
print('t3:' + DateTime.now().toString());
print(result);
} main() {
print('t1:' + DateTime.now().toString());
test();
print('t2:' + DateTime.now().toString());
}

future.whenComplete

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

import 'dart:async';
import 'dart:math'; void main() {
var random = Random();
Future.delayed(Duration(seconds: ), () {
if (random.nextBool()) {
return ;
} else {
throw 'boom!';
}
}).then(print).catchError(print).whenComplete(() {
print('done!');
});
}

future.timeout

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

import 'dart:async';

void main() {
new Future.delayed(new Duration(seconds: ), () {
return ;
}).timeout(new Duration(seconds: )).then(print).catchError(print);
}

运行上述代码会看到:TimeoutException after 0:00:02.000000: Future not completed

什么是FutureBuilder?

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

FutureBuilder的构造方法
FutureBuilder({Key key, Future<T> future, T initialData, @required AsyncWidgetBuilder<T> builder })
  • future: Future对象表示此构建器当前连接的异步计算;
  • initialData: 表示一个非空的Future完成前的初始化数据;
  • builder: AsyncWidgetBuilder类型的回到函数,是一个基于异步交互构建widget的函数;

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

connectionState - 枚举ConnectionState的值,表示与异步计算的连接状态,ConnectionState有四个值:none,waiting,active和done;

data - 异步计算接收的最新数据;

error - 异步计算接收的最新错误对象;

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

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

FutureBuilder的使用?

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http; void main() => runApp(new MyApp()); class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() => _MyAppState();
} class _MyAppState extends State<MyApp> {
String showResult = '';
Future<CommonModel> fetchPost() async {
final response = await http .get('http://www.devio.org/io/flutter_app/json/test_common_model.json');
Utf8Decoder utf8decoder = Utf8Decoder(); //fix 中文乱码
var result = json.decode(utf8decoder.convert(response.bodyBytes));
return CommonModel.fromJson(result);
} @override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Future与FutureBuilder实用技巧'),
), body: FutureBuilder<CommonModel>(
future: fetchPost(),
builder:
(BuildContext context, AsyncSnapshot<CommonModel> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return new Text('Input a URL to start');
case ConnectionState.waiting:
return new Center(child: new CircularProgressIndicator());
case ConnectionState.active:
return new Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return new Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return new Column(children: <Widget>[
Text('icon:${snapshot.data.icon}'),
Text('statusBarColor:${snapshot.data.statusBarColor}'),
Text('title:${snapshot.data.title}'),
Text('url:${snapshot.data.url}')
]);
}
}
}),
),
);
}
} class CommonModel {
final String icon;
final String title;
final String url;
final String statusBarColor;
final bool hideAppBar;
CommonModel(
{this.icon, this.title, this.url, this.statusBarColor, this.hideAppBar});
factory CommonModel.fromJson(Map<String, dynamic> json) {
return CommonModel(
icon: json['icon'],
title: json['title'],
url: json['url'],
statusBarColor: json['statusBarColor'],
hideAppBar: json['hideAppBar'],
);
}
}

Flutter 异步Future与FutureBuilder实用技巧的更多相关文章

  1. Flutter异步Future

    一.认识Future 1.创建Future void testFuture(){ Future future = new Future(() => null); future.then((_){ ...

  2. 总结vue知识体系之实用技巧

    vue 作为目前前端三大框架之一,对于前端开发者可以说是必备技能.那么怎么系统地学习和掌握 vue 呢?为此,我做了简单的知识体系体系总结,不足之处请各位大佬多多包涵和指正,如果喜欢的可以点个小赞!本 ...

  3. Notepad++ 实用技巧

    Notepad++是一款开源的文本编辑器,功能强大.很适合用于编辑.注释代码.它支持绝大部分主流的编程语言. 本文主要列举了本人在实际使用中遇到的一些技巧. 快捷键 自定义快捷键 首先,需要知道的是: ...

  4. javascript实用技巧、javascript高级技巧

    字号+作者:H5之家 来源:H5之家 2016-10-31 11:00 我要评论( ) 三零网提供网络编程. JavaScript 的技术文章javascript实用技巧.javascript高级技巧 ...

  5. iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

    iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https:// ...

  6. iOS开发实用技巧—在手机浏览器头部弹出app应用下载提示

    iOS开发实用技巧—在手机浏览器头部弹出app应用下载提示 本文介绍其简单使用: 第一步:在本地建立一个访问的服务端.  打开本地终端,在本地新建一个文件夹,在该文件夹中存放测试的html页面.   ...

  7. iOS开发实用技巧—项目新特性页面的处理

    iOS开发实用技巧篇—项目新特性页面的处理 说明:本文主要说明在项目开发中会涉及到的最最简单的新特性界面(实用UIScrollView展示多张图片的轮播)的处理. 代码示例: 新建一个专门的处理新特性 ...

  8. IOS 网络浅析-(十三 SDWebImage 实用技巧)

    IOS 网络浅析-(十三 SDWebImage 实用技巧) 首先让我描述一下为了什么而产生的实用技巧.(在TableView.CollectionView中)当用户所处环境WiFi网速不够快(不能立即 ...

  9. NSString的八条实用技巧

    NSString的八条实用技巧 有一篇文章写了:iOS开发之NSString的几条实用技巧 , 今天这篇,我们讲讲NSString的八条实用技巧.大家可以收藏起来,方便开发随时可以复制粘贴. 0.首字 ...

随机推荐

  1. centos ntfs-3g not find

    1,CentOS默认源里没有ntfs3g,想要添加ntfs支持,需要自己下载编译安装或者加源yum安装.我这里使用的是添加aliyun的epel源来yum安装的方式. 2,添加epel yum源wge ...

  2. [2019年湘潭大学程序设计竞赛(重现赛)H chat][背包dp]

    链接:https://ac.nowcoder.com/acm/contest/893/H来源:牛客网 题目描述 在Casya生活的世界里,一天由m个小时组成. 最近Casya的女神终于答应在接下来的n ...

  3. Time travel HDU - 4418 (概率DP)

    对于每个点两个方向(两头只有一个方向)建一个点,然后预处理出每个点走k(1≤k≤n)k(1\le k\le n)k(1≤k≤n)到哪个点,列出方程式高斯消元就行了.记得前面bfsbfsbfs出那些点不 ...

  4. HDU 6134 Battlestation Operational | 2017 Multi-University Training Contest 8

    破结论没听说过,上式推导到第三步的时候有了O(nlogn) 的做法(枚举倍数+1最后前缀和),并且这种做法可以直接应用到向上取整的计算中,详见forever97 但由于d(n)是积性函数,故可O(n) ...

  5. C#第一章 第一个C#程序

    第一个C#程序 namespace 是C#中组织代码的方式,它的作用那个类似java中的包 using 在Java中作用如果导入其他包 应该是用import关键字而在C#中应使用using关键字来引用 ...

  6. PHP mysqli_connect() 函数

    打开一个到 MySQL 服务器的新的连接: mysqli_connect(host,username,password,dbname,port,socket); <?php $con=mysql ...

  7. 001_项目开源之_STM32激光雕刻机

    我是标题:STM32激光雕刻机(开源免费) (一)首先感谢将离九歌   https://github.com/MaxwellXyao  提供的C8T6/GRBL的源码 (二)本设计开源(免费),请忽倒 ...

  8. web批量下载文件到本地

    JavaWeb 文件下载功能 文件下载的实质就是文件拷贝,将文件从服务器端拷贝到浏览器端,所以文件下载需要IO技术将服务器端的文件读取到,然后写到response缓冲区中,然后再下载到个人客户端. 1 ...

  9. cyk追楠神系列一(SDUT3703)

    cyk追楠神系列一 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Problem Description 众所周知,cyk ...

  10. 解析配置文件 redis.conf

    1.units单位 2.INCLUDES包含 3.GENERAL通用 1).daemonize daemonize yes 启用后台守护进程运行模式 2).pidfile pidfile /var/r ...