Flutter Future异步操作详细讲解
作者:lingjunjie 发布时间:2022-04-05 17:55:32
异步
future
Future 表示异步操作的结果 他有两种状态
未完成状态 :当调用异步函数时,他返回未完成的Future 并持续到异步函数操作完成;
完成状态:如果异步函数操作成功,则返回一个值;如果异步函数操作失败则返回一个错误
创建Future
import 'dart:match';
import 'dart:async';
int getInt(){
print('执行getInt的函数');
Random rng = Random();
return rng.nextInt(100);
}
void main(){
//此处调用的getint函数是int类型
Future<int> future = Future(getInt);
//验证是否Future<int>的实例
print(Future(getInt));
}
异步创建
import 'dart:match';
import 'dart:async';
int getInt() async{
print('执行getInt的函数');
Random rng = Random();
return rng.nextInt(100);
}
void main(){
//此处调用的getint函数是int类型
Future<int> future = Future(getInt);
//验证是否Future<int>的实例
print(Future(getInt));
}
使用Future
Future的类提供 then catchError whenCompete 三个函数对Future对象进行进一步处理,当异步操作成功时 执行then方法,then方法接受一个参数为异步操作返回值的回调函数。当异步操作失败时,执行catchError方法,catchError方法接受一个参数为错误对象的回调函数。当异步操作完成的时候无论失败还是成功都会调用whenCompete,而且wehnCompete方法接受一个无参的回调函数。
import 'dart:match';
import 'dart:async';
int getInt(){
print('执行getInt的函数');
Random rng = Random();
return rng.nextInt(100);
}
void main(){
//此处调用的getint函数是int类型
Future<int> future = Future(getInt);
future.then((Object onValue){
print('异步调用成功,值为$onValue');
}).catchError((Object onError){
print('异步调用失败,值为$onError');
}).whenCompete((){
print('异步操作完成');
});
}
也可以使用await等待异步操作完成,使用await关键字必须使用async标记 ,并且使用try关键字捕获异常。
import 'dart:match';
import 'dart:async';
int getInt(){
print('执行getInt的函数');
Random rng = Random();
return rng.nextInt(100);
}
void main() async{
//此处调用的getint函数是int类型
Future<int> future = Future(getInt);
try{
//使用await等待异步调用完成使其等同意同步代码
var onvalue = await getInt();
print('一步操作成功:$onvalue');
}on Excrption catch(onError){
print('异步捕获失败:$onError');
}finally{
print('异步捕获完成');
}
}
await关键字
在await表达式中,其值通常是Future,如果不是则会自动包装到Future中。Future关键字表示承诺返回一个对象。await表达式的值就是返回的对象。await表达式使执行暂停直到该对象可用为止。
如果异步不需要返回值,则将返回类型修改为Future< void >
Stream
Stream 是一系列异步事件的源。Stream提供了一种接收时间序列的方式,每个事件要么是数据事件 要么是错误事件(发生故障时的通知),当Stream发出所有事件后,单个done事件将通知侦 听器已完成。
stream和Future的区别
1. Future在异步操作中提供单个结果、错误、或者值。Stream提供多个结果;
2. Future 通过函数处理结果,Stream通过listen;
3. Future发送接收相同的值,Stream 可以使用辅助方法在值到达前处理;
//创建Stream
StreamController<int> controller = StreamController<int>(
onListen: startTimer,
onPause: stopTimer,
onResume: startTimer,
onCAncel: stoptimer
);
Stream stream = controller.stream;
StreamController 构造函数支持泛型,这里使用int类型。后遭函数提供了多个可选参数:
4. onlisten:监听Stream时调用的回调函数
5. onpause: 暂停调用的回调函数
6. onreaume: 恢复调用的回调函数
7. oncancel: 取消stream调用的回调函数
8. sync 布尔值,默认false ,同步stream标记
使用Stream
import 'dart:async';
Stream<int> createStream(Duration interval,int maxCount){
//定义流控制器
StreamController<int> controller;
//定义定时器
Timer timer;
//计数变量
int counter= 0
void tick(_){
counter++;
controller.add(counter);
//判断计数变量是否达到了最大值
if(counter == maxCount){
//关闭计时器
timer.cancel();
//关闭Stream并通知 *
controller.clase();
}
}
//启动计时器
void startTimer(){
timer = Timer.periodic(interval,tick);
}
void stopTimer(){
if (timer != null){
timer.cancel();
timer = null;
}
print('结束执行');
}
controller = StreamController<int>(
onListen: startTimer,
onPause: stopTimer,
onResume: startTimer,
onCAncel: stoptimer
);
return controller.stream;
}
void main() async{
Stream<int> stream = createStream(const Duration(senconds:1),10);
stream.listen((int value){
print('来自createStream的值:$value');
});
}
生成器函数
传统函数只会返回个单个值,生成器函数生成值的序列。生成器函数可以采用同步返回带有值的 Iterable 对象,在一部中返回Stream对象
关键字yield 返回单个值到序列,但不会停止生成器函数 。
生成器函数按需生成值,当开始迭代 iterator 或者开始监听 stream 才生成值。
同步生成器
Interable<int> getNumbers(int number) sync* (
print('开始执行');
int k=0;
while(k<number) yield k++;
print('生成器执行结束');
)
void main (){
print('创建interator');
for (int val in numbers){
print('$val');
}
}
异步生成器
Interable<int> getNumbers(int number) async* (
print('开始执行');
int k=0;
while(k<number) yield k++;
print('生成器执行结束');
)
void main (){
print('创建interator');
for (int val in numbers){
print('$val');
}
}
递归生成器
Interable<int> getNumberRecursive(int number) sync* (
print('开始执行,输出number:$number');
if(numner>0){
yield* getNumberRecursive(number - 1);
}
print('生成器执行结束number:$number');
)
void main (){
print('创建interator');
Interable<int> numbers = getNumberRecursive(3);
for (int val in numbers){
print('$val');
}
}
来源:https://blog.csdn.net/lingjunjie/article/details/129362482


猜你喜欢
- springmvc的图片上传1.导入相应的pom依赖 <dependency> <groupId>co
- 本文实例讲述了java实现一次性压缩多个文件到zip中的方法。分享给大家供大家参考,具体如下:1.需要引入包:import java.io.
- Springboot导出文件,前端下载文件后端代码可以把请求设置为post,我这里是Get @RequestMapping(value =
- 这个窗口是右下角提示小窗口,主要用于提示。private void btnStartNotification_Click(object se
- 本文接上文“java反射之获取类的信息方法(推荐)”,利用反射(invoke)来获取一个类中的方法来执行。1、定义一个类,包含三个名称相同,
- 前言CMake是一个跨平台的安装编译工具,可以用简单的语句来描述所有平台的安装(编译过程)。CMake可以说已经成为大部分C++开源项目标配
- 前面两篇文章,分别简述了多线程的使用和发展历程,但是使用多线程无法避免的一个问题就是多线程安全。那什么是多线程安全?如何解决多线程安全?本文
- 本文主要对SpringBoot2.x参数校验进行简单总结,其中SpringBoot使用的2.4.5版本。一、引入依赖<dependen
- 准备工作:import java.text.SimpleDateFormat;import java.util.Calendar;impor
- 芬兰数学家因卡拉花费3个月设计出了世界上迄今难度最大的数独游戏,而且它只有一个答案。因卡拉说只有思考能力最快、头脑最聪明的人才能破解这个游戏
- 本文实例讲述了Java正则验证正整数的方法。分享给大家供大家参考,具体如下:package des;import java.util.reg
- 在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过。源码下载:http://xiazai.jb51.net/
- 本文主要介绍了C# WinForm状态栏实时显示当前时间(窗体状态栏StatusStrip示例),分享给大家,具体如下:实现效果:通过Sta
- AOP我想大家都很清楚,有时候我们需要处理一些请求日志,或者对某些方法进行一些监控,如果出现例外情况应该进行怎么样的处理,现在,我们从spr
- 下面通过一段内容有文字说明有代码分析,并附有展示图供大家学习。要解析HTTP报文,需要实现以下操作:读取HTTP报头提供的各种属性分析属性值
- 一、简介在Spring中,有这么2个接口:BeanFactory和FactoryBean,名字很相似,很多小伙伴经常混淆,在面试的时候也经常
- 上一篇文章我们介绍了Apache Commons Math3学习之数值积分实例代码,这里给大家分享math3多项式曲线拟合的相关内容,具体如
- 本文实例为大家分享了C# Winform实现圆角无锯齿按钮的具体代码,供大家参考,具体内容如下发现用Winform做一个圆角按钮遇到麻烦,主
- 1. String对象不可改变的特性下图显示了如下代码运行的过程:String s = "abcd"; s = s.co
- 前言日志处理是每个项目当中一个非常重要的内容。没有了日志,也就失去了对系统的可控性。没有日志,系统出现任何问题,都会没有踪迹可寻,这对一个信