Flutter-----异步编程:Future和Stream

异步编程:使用 Future 和 async-await | Dart

什么是异步操作/异步操作的作用?

Dart 代码运行在单个执行"线程"中。如果 Dart 代码在执行时阻塞,例如:处理一个需要长时间运行的计算操作或等待 I/O 完成。此时整个程序会被"冻结"。

异步操作可以让你的程序在等待一个操作完成时继续处理其它的工作。Dart 使用 Future 对象来表示异步操作的结果。异步计算不会阻塞所有计算直到结果可用,而是立即返回一个 Future最终将"完成"结果

future是什么?

future 是 Future<T> 类的对象,其表示一个 T 类型的异步操作结果。如果异步操作不需要结果,则 future 的类型可为 Future<void>。当一个返回 future 对象的函数被调用时,会发生两件事:

  1. 将函数操作列入队列等待执行并返回一个未完成的 Future 对象。

  2. 不久后当函数操作执行完成,Future 对象变为完成并携带一个值或一个错误。

如何使用future?

使用关键字 asyncawait

asyncawait的作用?

它们允许你不使用 Future 的 API (Future.then和Future.catchError)编写看起来与同步代码一样的异步代码。

  • 在异步函数中使用 await 关键字暂停代码的执行,直到对应的 future 完成。

  • 可以使用 try-catch 表达式来捕获异步函数中代码的执行错误。

case1:

复制代码
/// 新建的Future学习类
class FutureStudy{

  // 延时1秒钟
  Future<void> futureDelay() async {
    await Future.delayed(new Duration(seconds: 1),() =>print("1秒后打印-延时任务"));
  }
}

main() async {
  // 调用 FutureStudy 中的延时方法 -延时在前 正常在后
  FutureStudy().futureDelay();
  print("正常打印");
}

打印结果:延时语句在前但是却后打印,这是因为:

await Future.delayed(new Duration(seconds: 1),() =>print("1秒后打印-延时任务")); 会阻塞一秒钟

而异步操作可以让你的程序在等待一个操作完成时继续处理其它的工作

I/flutter ( 3898): 正常打印

I/flutter ( 3898): 1秒后打印-延时任务

case2:

复制代码
main() async {
  // 调用 FutureStudy 中的延时方法 -延时在前 正常在后
  await FutureStudy().futureDelay();
  print("正常打印");
}

I/flutter ( 3898): 1秒后打印-延时任务

I/flutter ( 3898): 正常打印

此时先打印延时方法里的是因为:

main中 await FutureStudy().futureDelay()需要先等待futureDelay()内部方法完成后再执行后面的语句,所以体现的是一个同时操作的效果。

case3:

在此基础上修改 FutureStudy 中的代码

复制代码
class FutureStudy{
  futureDelay() async {
    // 模拟延时效果 - 等待两秒后再执行
    Future.delayed(const Duration(seconds: 1),() =>print("1秒后打印-延时任务"));
  }
}

I/flutter ( 3898): 正常打印

I/flutter ( 3898): 1秒后打印-延时任务

此时的打印结果和case1相同,这是因为main中 await FutureStudy().futureDelay() 要等待函数执行完成后再执行其他语句,但是函数内部遵循的是异步操作,此时它可以执行其他语句。

使用 Future API

由于Future可以通过两种方式完成,要么使用值(如果异步计算成功),要么使用错误(如果计算失败),因此可以为其中一种或两种情况安装回调。

Future的所有API的返回值仍然是一个Future对象,Future.then可以使用这个future。

复制代码
Future<R> then<R>(FutureOr<R> onValue(T value), {Function? onError});

then()会在 Future函数体执行完毕后立刻执行

如果,future是作为值返回的,则调用回调函数 onValue 回调函数,里面的参数是value去future返回的值,如果future的结果是错误则调用 onError 回调函数

then中的回调onError和Future.catchError

Future.catchError回调只处理原始Future抛出的错误,不能处理回调函数抛出的错误,onError只能处理当前Future的错误

Future.whenComplete

Future.whenComplete 在Future完成之后总是会调用,不管是错误导致的完成还是正常执行完毕

Future.wait

等待多个Future完成,并收集它们的结果。有两种情况

  • 所有Future都有正常结果返回。则Future的返回结果是所有指定Future的结果的集合
  • 其中一个或者几个Future发生错误,产生了error。则Future的返回结果是第一个发生错误的Future的值

Future.foreach

根据某个集合对象,创建一系列的Future。并且会按顺序执行这些Future

复制代码
void testFuture() async {
    Future.forEach({1,2,3}, (num){
      return Future.delayed(Duration(seconds: num),(){print("第$num秒执行");});
    });
}
testFuture();
print("在testFuture()执行之后打印。");

处理Stream流

异步编程:使用 stream | Dart

相关推荐
贫道绝缘子12 分钟前
【Android】四大组件之Service
android
weixin_4723394628 分钟前
Android Studio下载安装教程
android·ide·android studio
仙魁XAN1 小时前
Flutter 学习之旅 之 flutter 有时候部分手机【TextField】无法唤起【输入法软键盘】的一些简单整理
flutter·unity·华为手机·textfield·键盘唤不起
tangweiguo030519871 小时前
Android Kotlin 依赖注入全解:Koin appModule 配置与多 ViewModel 数据共享实战指南
android·kotlin
西楚曹长卿1 小时前
RN 获取视频封面,获取视频第一帧
android·react native·音视频·react
建群新人小猿2 小时前
CRMEB-PRO系统定时任务扩展开发指南
android·java·开发语言·前端
leluckys2 小时前
flutter 专题 五十八 关于Flutter提示Your Xcode project requires migration的错误
flutter
百流3 小时前
ES使用之查询方式
android·大数据·elasticsearch
每次的天空4 小时前
Android学习总结之自定义view设计模式理解
android·学习·设计模式
是店小二呀4 小时前
【优选算法 | 前缀和】前缀和算法:高效解决区间求和问题的关键
android·c++·算法