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函数内部使用

相关文章
|
移动开发 Dart JavaScript
Flutter for Web 首次首屏优化——JS 分片优化
Flutter for Web 首次首屏优化——JS 分片优化
1707 1
Flutter for Web 首次首屏优化——JS 分片优化
|
监控 容灾 测试技术
怎么保证后端服务稳定性,怎么做容灾
【10月更文挑战第25天】在实际应用中,需要根据具体的业务需求、预算和风险承受能力等因素,选择合适的稳定性保障和容灾方案,并不断优化和完善,以适应不断变化的业务环境和技术发展
|
运维 C# UED
C# 一分钟浅谈:异常处理的最佳实践
【9月更文挑战第5天】在软件开发中,异常处理对保证程序稳定性和用户体验至关重要。本文从基础概念入手,详细讲解C#中的异常处理策略,并通过代码示例说明如何有效实现异常管理。文章涵盖`try`、`catch`和`finally`块的使用,探讨常见问题如忽略异常和过度捕获,并提出最佳实践建议,如使用具体异常类型、记录异常信息及优雅地处理异常,助力开发者构建更健壮的应用程序。
680 1
|
弹性计算 人工智能 测试技术
阿里云服务器租用收费标准价格表(2023年更新)
阿里云服务器租用收费标准价格表(2023年更新)
860 0
|
监控 Linux 网络安全
Centos7下多种方式配置 Apache虚拟主机
Centos7下多种方式配置 Apache虚拟主机
1379 1
Centos7下多种方式配置 Apache虚拟主机
|
应用服务中间件 Apache PHP
Apache vs Nginx: 实际考虑因素
Apache vs Nginx: 实际考虑因素
406 0
|
数据采集 机器学习/深度学习 数据挖掘
基于Python实现时间序列分析建模(ARIMA模型)项目实战
基于Python实现时间序列分析建模(ARIMA模型)项目实战
|
存储 分布式计算 监控
分布式系统详解--框架(Hadoop-HDFS的HA搭建及测试)
分布式系统详解--框架(Hadoop-HDFS的HA搭建及测试)
248 0
|
搜索推荐
EDM营销应该如何制作使用?邮件营销方法
EDM营销通过电子邮件推广产品,关键步骤包括:明确营销目标,如销售额增长或品牌知名度提升;精准定位受众,依据受众特征定制内容;设计吸引人的标题和内容,结合图片或视频;运用个性化信息提升互动性;定期发送保持联系;监测邮件效果如打开率和点击率;并根据分析结果持续优化策略。这些方法能有效提升邮件营销效率和成果。
|
关系型数据库 MySQL 索引
mysql中force index强制索引
mysql中force index强制索引
318 0