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

目录
打赏
0
2
2
0
3
分享
相关文章
Flutter ListView懒加载(滑动不加载,停止滑动加载)
前言:为了更好的减小网络的带宽,使得列表更加流畅,我们需要了解懒加载,也称延迟加载。关于上一章的登录界面,各位属实难为我了,我也在求ui小姐姐,各位点点赞给我点动力吧~
Flutter笔记:滚动之-无限滚动与动态加载的实现
Flutter笔记:滚动之-无限滚动与动态加载的实现
479 0
Android Studio New里面没有New Flutter Project
Android Studio New里面没有New Flutter Project
322 1
Android Studio New里面没有New Flutter Project
【Flutter前端技术开发专栏】Flutter中的手势识别与触摸事件处理
【4月更文挑战第30天】本文探讨了Flutter中的手势识别和触摸事件处理,关键点包括: 1. 使用`GestureRecognizer`类体系实现手势识别,如`TapGestureRecognizer`检测点击,`HorizontalDragGestureRecognizer`和`VerticalDragGestureRecognizer`识别滑动,`ScaleGestureRecognizer`识别捏合和扩张。
268 0
【Flutter前端技术开发专栏】Flutter中的手势识别与触摸事件处理
Flutter的网络请求:使用Dart进行HTTP请求的技术详解
【4月更文挑战第26天】了解Flutter网络请求,本文详述使用Dart进行HTTP请求
【数据结构】C语言实现顺序栈(附完整运行代码)
【数据结构】C语言实现顺序栈(附完整运行代码)
309 0
Flutter笔记:目录与文件存储以及在Flutter中的使用(下)
Flutter笔记:目录与文件存储以及在Flutter中的使用(下)
1137 0
为什么说 Compose 的声明式代码最简洁 ?Compose/React/Flutter/SwiftUI 语法对比
为什么说 Compose 的声明式代码最简洁 ?Compose/React/Flutter/SwiftUI 语法对比
363 1
【Unity 3D】使用EasyAR实现单图识别的AR增强现实功能(附实现步骤)
【Unity 3D】使用EasyAR实现单图识别的AR增强现实功能(附实现步骤)
597 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等