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

相关文章
|
4天前
|
前端开发
async和await 优雅处理异步
async和await 优雅处理异步
|
4天前
|
前端开发 Python
探索Python中的异步编程:从回调到async/await
本文将深入探讨Python中的异步编程模式,从最初的回调函数到现代的async/await语法。我们将介绍异步编程的基本概念,探讨其在Python中的实现方式,以及如何使用asyncio库和async/await语法来简化异步代码的编写。通过本文,读者将能够全面了解Python中的异步编程,并掌握使用异步技术构建高效、响应式应用程序的方法。
|
4天前
|
前端开发 JavaScript Java
Promise, async, await实现异步编程,代码详解
Promise, async, await实现异步编程,代码详解
21 1
|
4天前
|
Rust 安全 程序员
Rust中的异步编程:Futures与Async/Await的深入解析
Rust作为一种系统级编程语言,近年来因其内存安全、高性能和并发处理能力而受到广泛关注。在Rust中,异步编程是实现高效并发处理的关键。本文将探讨Rust中的异步编程概念,详细介绍Futures与Async/Await这两种主要实现方式,并解析它们在实际应用中的优势与挑战。
|
4天前
|
监控 前端开发 JavaScript
等一下!深入async/await的异步世界
等一下!深入async/await的异步世界
51 1
|
9月前
|
前端开发 JavaScript
async、await 实现原理
async、await 实现原理
54 1
|
消息中间件 前端开发 JavaScript
ES8 中的 async/await —— 异步函数
ES8 中的 async/await —— 异步函数
152 0
async和await用法(Task)
原文:async和await用法 要理解async和await的用法,首先要了解Task相关知识,这里不做说明,因为这不是本文的重点。 如果你已经对Task很了解,那么如何使用async和await,在此主要总结了以下三点: 只有在async方法里面才能使用await操作符; await操作符是针对Task对象的; 当方法A调用方法B,方法B方法体内又通过await调用方法C时,如果方法C内部有异步操作,则方法B会等待异步操作执行完,才往下执行;但方法A可以继续往下执行,不用再等待B方法执行完。
1306 0
C#多线程(18):一篇文章就理解async和await
C#多线程(18):一篇文章就理解async和await
223 0
C#多线程(18):一篇文章就理解async和await