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

相关文章
|
6月前
|
前端开发
async和await 优雅处理异步
async和await 优雅处理异步
|
2月前
|
C# UED
C#一分钟浅谈:异步编程基础 (async/await)
在现代软件开发中,异步编程对于提升应用性能和响应性至关重要,尤其是在处理网络请求和文件读 异步编程允许程序在等待操作完成时继续执行其他任务,从而提高用户体验、高效利用资源,并增强并发性。在 C# 中,`async` 用于标记可能包含异步操作的方法,而 `await` 则用于等待异步操作完成。 示例代码展示了如何使用 `async` 和 `await` 下载文件而不阻塞调用线程。此外,本文还讨论了常见问题及解决方案,如不在 UI 线程上阻塞、避免同步上下文捕获以及正确处理异常。
48 0
|
3月前
|
C#
C# async await 异步执行方法
C# async await 异步执行方法
51 0
|
5月前
|
JSON 前端开发 JavaScript
ES6引入Promise和async/await解决异步问题
【6月更文挑战第12天】ES6引入Promise和async/await解决异步问题。Promise处理异步操作,有pending、fulfilled、rejected三种状态,支持链式调用和并行处理。async/await是基于Promise的语法糖,使异步代码更同步化,提高可读性。两者都是处理回调地狱的有效工具,开发者应根据需求选择合适的方式。
54 3
|
6月前
|
监控 前端开发 JavaScript
等一下!深入async/await的异步世界
等一下!深入async/await的异步世界
90 1
|
前端开发 JavaScript
async、await 实现原理
async、await 实现原理
78 1
|
消息中间件 前端开发 JavaScript
ES8 中的 async/await —— 异步函数
ES8 中的 async/await —— 异步函数
190 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方法执行完。
1330 0
C#多线程(18):一篇文章就理解async和await
C#多线程(18):一篇文章就理解async和await
260 0
C#多线程(18):一篇文章就理解async和await