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

相关推荐
泥嚎泥嚎25 分钟前
【Android】给App添加启动画面——SplashScreen
android·java
全栈派森33 分钟前
初见 Dart:这门新语言如何让你的 App「动」起来?
android·flutter·ios
q***985237 分钟前
图文详述:MySQL的下载、安装、配置、使用
android·mysql·adb
恋猫de小郭1 小时前
Dart 3.10 发布,快来看有什么更新吧
android·前端·flutter
恋猫de小郭3 小时前
Flutter 3.38 发布,快来看看有什么更新吧
android·前端·flutter
百锦再8 小时前
第11章 泛型、trait与生命周期
android·网络·人工智能·python·golang·rust·go
会跑的兔子9 小时前
Android 16 Kotlin协程 第二部分
android·windows·kotlin
键来大师9 小时前
Android15 RK3588 修改默认不锁屏不休眠
android·java·framework·rk3588
江上清风山间明月12 小时前
Android 系统超级实用的分析调试命令
android·内存·调试·dumpsys
百锦再12 小时前
第12章 测试编写
android·java·开发语言·python·rust·go·erlang