Dart异步之Future以及async、await的使用

简介: Dart异步之Future以及async、await的使用

Dart是一门单线程的语言,我们在开发进行耗时操作(比如网络请求、数据库存储、文件读取)时会阻塞我们的程序,Dart的并发机制可以在等待一个操作完成的同时进行别的操作,在Dart中执行异步操作,可以用Future类和async、await关键字;这里主要介绍Future以及async和await的使用,具体原理参考下一篇文章;

Future的使用

  • then

通过then获取Future的执行结果

void test1() {
    print("start");
    thenCase().then((value) {
      print("then - value = $value");
    });
    print("end");
  }
  Future<String> thenCase() {
    return Future(() {
      return "测试then";
    });
  }

运行结果

flutter: start
flutter: end
flutter: then - value = 测试then
  • onError & catchError

catchError既能接收then里面的错误又能接收onError里面的错误

class FltError implements Exception {
    int errCode = 0;
    String? msg;
}
void test2() {
  print("start");
  catchErrorCase().then((value) {
    print("then - value = $value");
  }).onError((error, stackTrace) {
    if (error is FltError) {
      FltError err = error as FltError;
      print("FltError - obj - ${err.msg}");
    }else {
      print("other - error - $error");
    }
    throw error!;
  }).catchError((error) {
    print("catchError - ${error.runtimeType}");
  });
  print("end");
}
Future<String> catchErrorCase() {
  return Future(() {
    FltError error = FltError();
    error.msg = "测试返回error";
    error.errCode = 200;
    throw error;
  });
}

运行结果

flutter: start
flutter: end
flutter: FltError - obj - 测试返回error
flutter: catchError - FltError
  • whenComplete

无论正常还是异常,Future均会执行该回调

void test3() {
  print("start");
  catchErrorCase().then((value) {
    print("then - value = $value");
  }).onError((error, stackTrace) {
    if (error is FltError) {
      FltError err = error as FltError;
      print("FltError - obj - ${err.msg}");
    }else {
      print("other - error - $error");
    }
    throw error!;
  }).catchError((error) {
    print("catchError - ${error.runtimeType}");
  }).whenComplete(() {
    print("whenComplete");
  });
  print("end");
}

运行结果

flutter: start
flutter: end
flutter: FltError - obj - 测试返回error
flutter: catchError - FltError
flutter: whenComplete
  • delay

异步延时执行一个任务

void test4() {
  print("start - ${DateTime.now()}");
  delayed().then((value) {
    print("value = $value");
  });
  print("end - ${DateTime.now()}");
}
Future<String> delayed() {
  return Future<String>.delayed(Duration(seconds: 3), () {
    return "异步延时执行任务 + ${DateTime.now()}";
  });
}

运行结果

flutter: start - 2023-03-20 15:29:09.997512
flutter: end - 2023-03-20 15:29:10.006552
flutter: value = 异步延时执行任务 + 2023-03-20 15:29:13.007373
  • value

直接创建一个带值的Future,如下代码:

void valueTest() {
  Future.value("1").then((value) {
    print("v1 - $value");
  });
  Future(() {
    return "2";
  }).then((value) {
    print("v2 - $value");
  });
}

运行结果

flutter: v1 - 1
flutter: v2 - 2
• wait

等待数组中的每一个都执行完成,再执行then

void test5() {
  Future v1 = delayed(1);
  Future v2 = delayed(2);
  Future.wait([v1, v2]).then((value) {
    print("then - \nvalue0 = ${value[0]} \nvalue1 = ${value[1]}\ntime = ${DateTime.now()}");
  });
}
Future delayed(int value) {
  return Future.delayed(Duration(seconds: value), () {
    return "异步延时执行任务 - value = $value - time = ${DateTime.now()}";
  });
}

运行结果(注意换行符)

flutter: then -
value0 = 异步延时执行任务 - value = 1 - time = 2023-03-20 15:44:25.578118
value1 = 异步延时执行任务 - value = 2 - time = 2023-03-20 15:44:26.579086
time = 2023-03-20 15:44:26.579965
  • any

有任意一个Future完成就结束

void test6() {
  Future v1 = delayed(1);
  Future v2 = delayed(2);
  Future.any([v1, v2]).then((value) {
    print("then - value = $value - time = ${DateTime.now()}");
  }).whenComplete(() {
    print("whenComplete");
  });
}
Future delayed(int value) {
  return Future.delayed(Duration(seconds: value), () {
    return "异步延时执行任务 - value = $value - time = ${DateTime.now()}";
  });
}

运行结果

flutter: then - value = 异步延时执行任务 - value = 1 - time = 2023-03-20 15:47:39.451636 - time = 2023-03-20 15:47:39.453878
flutter: whenComplete
  • timeout

注意参数传入的是3,duration是2

void test7() {
  print("${DateTime.now()} - start");
  delayed(3).then((value) {
    print("${DateTime.now()} - then - $value");
  }).timeout(Duration(seconds: 2)).then((value) {
    print("${DateTime.now()} - timeout = $value");
  }).catchError((error) {
    print("${DateTime.now()} - timeout - error - ${error.runtimeType}");
  }).whenComplete(() {
    print("${DateTime.now()} - whenComplete");
  });
  print("${DateTime.now()} - end");
}
Future delayed(int value) {
  return Future.delayed(Duration(seconds: value), () {
    return "异步延时执行任务";
  });
}

运行结果

flutter: 2023-03-20 15:56:14.055962 - start
flutter: 2023-03-20 15:56:14.065781 - end
flutter: 2023-03-20 15:56:16.071233 - timeout - error - TimeoutException
flutter: 2023-03-20 15:56:16.071578 - whenComplete
flutter: 2023-03-20 15:56:17.064688 - then - 异步延时执行任务

将参数传入的是1,duration是2,运行结果

flutter: 2023-03-20 15:58:02.800739 - start

flutter: 2023-03-2015:58:02.811208 - end

flutter: 2023-03-2015:58:03.811116 - then - 异步延时执行任务

flutter: 2023-03-2015:58:03.811733 - timeout = null

flutter: 2023-03-2015:58:03.811959 - whenComplete

async、await

异步处理:在返回的 Future 对象上注册一个then,等 Future 的执行体结束以后,再进行异步处理同步等待;

同步等待:Future 执行体结束,此时需要在调用处使用await,在调用处的函数体使用 async;

void test8() {
  print("start");
  asyncTest();
  print("end");
}
void asyncTest() async {
  var result = await Future.value(1);
  print("result = $result");
}

运行结果

flutter: start
flutter: end
flutter: result = 1

注意:await关键字必须在async函数内部使用

相关文章
|
18天前
|
Dart 安全
Flutter - dart 语言从入门到精通
本文系统解析 Dart 语言的基础与高级语法,涵盖变量类型、函数、面向对象、泛型、异步编程(Future/Stream)、空安全、mixin、扩展方法等核心特性,助你掌握 Flutter 开发基石,提升代码质量与开发效率。
155 10
|
4月前
|
Ubuntu 安全 Linux
Ubuntu 24.10 发行版登场:Linux 6.11 内核、GNOME 47 桌面环境
Ubuntu 24.10 还带来了 GNOME 47,增强了性能和稳定性,并引入了新功能。此版本的 Ubuntu 还默认在采用 Nvidia 显卡的硬件上切换到 Wayland,并在支持的硬件上默认使用开源的 Nvidia 560 内核模块。 另外需要注意的是,Ubuntu 24.10 是稳定版本,但作为非 LTS 版本,仅支持 9 个月。
|
移动开发 Dart JavaScript
Flutter for Web 首次首屏优化——JS 分片优化
Flutter for Web 首次首屏优化——JS 分片优化
1741 1
Flutter for Web 首次首屏优化——JS 分片优化
|
Java
【Java基础】输入输出流(IO流)
Java基础、输入输出流、IO流、流的概念、输入输出流的类层次结构图、使用 InputStream 和 OutputStream流类、使用 Reader 和 Writer 流类
441 2
|
搜索推荐 Java UED
SpringBoot 自定义启动画面:打造个性化应用启动体验
【10月更文挑战第7天】在软件开发中,细节往往能够体现一个团队的专业性和对用户体验的关注。SpringBoot作为快速构建Spring应用的框架,其简洁的启动流程和强大的功能深受开发者喜爱。然而,默认的启动画面可能略显单调,无法充分展示应用的特色或品牌。本文将详细介绍如何为SpringBoot应用自定义启动画面,让应用在启动时就能给人留下深刻印象。
423 1
|
弹性计算 人工智能 测试技术
阿里云服务器租用收费标准价格表(2023年更新)
阿里云服务器租用收费标准价格表(2023年更新)
882 0
|
监控 Linux 网络安全
Centos7下多种方式配置 Apache虚拟主机
Centos7下多种方式配置 Apache虚拟主机
1404 1
Centos7下多种方式配置 Apache虚拟主机
|
存储 PyTorch 算法框架/工具
Transformers 4.37 中文文档(十九)(4)
Transformers 4.37 中文文档(十九)
637 2
|
应用服务中间件 Apache PHP
Apache vs Nginx: 实际考虑因素
Apache vs Nginx: 实际考虑因素
422 0

热门文章

最新文章