Dart 异步函数 Async,await,Future相关理解

在Dart的单线程环境中,无法使用多线程进行耗时操作,而是借助异步机制,如async和await关键字配合Future处理网络请求、数据库操作等。异步方法在遇到await后会暂停执行,等待任务完成后再继续,期间不会阻塞主线程。Future表示一个未来的值,可以在异步方法中返回。通过示例解释了异步执行的顺序和Future的作用。

前言

因为在Dart语言中是单线程模型,所以不能像java那样利用多线程的特性开一个子线程,在子线程中来进行耗时操作。因此,我们需要用异步的方式来进行耗时操作,如网络请求、数据库操作、文件读写等。

例子

首先,在pubspec.yaml文件中加入依赖

dependencies:
  http: ^0.13.5

然后,新建一个dart文件来尝试怎么运用异步操作,我们定义了一个私有方法startMethod(),并标记为async,表明这是一个异步方法,在这个方法里打印3条语句,嵌套了一个getHttp()方法。

getHttp()方法也是一个异步方法,并且进行了耗时操作(网络请求),返回一个字符串。这时可能大家就有疑惑,为啥方法返回值是Future,但我返回字符串也可以呢?别着急,接着往下看。

import 'package:http/http.dart' as http;

main(){
  _startMethod();
  print("C start");
}

Future _startMethod() async{
  print('A start');
  print(await getHttp());
  print('A end');
}
Future getHttp() async{
  final result = await http.get(Uri.https('jianshu.com'));
  return 'result :${result.headers}';
}

运行main方法,得到的返回值如下:

A start
C start
result :{...}
A end

程序按顺序运行,第一行打印没有什么问题,但是为啥第二行直接打印的是C start呢,这就是Dart语言中异步方法的作用了。

在async方法中,在遇到await之前的语句都正常执行,遇到await之后的方法都进行等待,并执行await后面的代码(请求http),等到结果返回才继续执行下面的代码。

且遇到await时该方法(_startMethod)会立即返回一个Future,不影响上层调用的执行(打印 C start)

tips

在这里其实省略了一个Future的用法,Future其实后面会跟一个泛型,代表这个函数未来会返回一个什么类型的结果

未省略版:

import 'package:http/http.dart' as http;

main(){
  _startMethod();
  print("C start");
}

Future<void> _startMethod() async{
  print('A start');
  print(await getHttp());
  print('A end');
}
Future<String> getHttp() async{
  final result = await http.get(Uri.https('jianshu.com'));
  return 'result :${result.headers}';
}

语法

Working with futures: async and await

The async and await keywords provide a declarative way to define asynchronous functions and use their results. Remember these two basic guidelines when using async and await:

  • To define an async function, add async before the function body:
  • The await keyword works only in async functions. 

在定义异步函数时,async必须在函数体之前

await 关键字必须在 异步函数中才有用

进阶

接下来,我们在getHttp()方法中加入两行打印,再来查看运行结果

import 'package:http/http.dart' as http;

main(){
  _startMethod();
  print("C start");
}

Future _startMethod() async{
  print('A start');
  print(await getHttp());
  print('A end');
}
Future getHttp() async{
  print('B http start');
  final result = await http.get(Uri.https('jianshu.com'));
  print('B http end');
  return 'result :${result.headers}';
}

结果如下:

A start
B http start
C start
B http end
result :{...}
A end

刚开始看到这个结果,可能会有点转不过来。这里其实是一种递归的思想,我们按照规则一步步走就很好理解了。

程序按顺序执行,首先打印 A start 然后,执行print(await getHttp()),_startMethod方法开始等待。

然后打印 b http start ,继续执行http.get方法,getHttp开始等待。因为没有执行完http.get,所以向_startMethod返回一个Future。同理,print(await getHttp())没有执行完,_startMethod返回一个Future,main方法同步执行C start。

当http.get执行完毕后,继续执行 B http end,打印 result, A end。

参考

Asynchronous programming: futures, async, await | Dart

Dart 中 Async 、 await 、Future 特性 - 简书

### Dart 中 `async` 和 `await` 的使用 在 Dart 编程语言中,`async` 和 `await` 关键字用于处理异步操作。通过这些关键字可以使代码更简洁易读。 #### 基本概念 - **`async`**: 当一个函数被标记为 `async` 后,在该函数体内可以使用 `await` 来暂停当前执行直到某个异步操作完成[^1]。 - **`await`**: 此关键字只能出现在带有 `async` 标记的方法内,它使得程序能够等待一个 Future 对象的结果而不会阻塞整个应用程序线程[^2]。 #### 示例代码展示 下面是一个简单的例子来说明如何利用 `async` 和 `await` 实现多个异步任务按序执行: ```dart import 'dart:async'; void main() { getName1(); } // 定义了一个异步方法 getName1() async { String result1 = await getStr1(); // 等待getStr1()返回结果 print(result1); // 输出result1 String result2 = await getStr2(); // 继续等待getStr2()返回结果 print(result2); // 输出result2 print('getName1'); } Future<String> getStr1() async { await Future.delayed(Duration(seconds: 1)); // 模拟耗时操作 return "这是来自getStr1的消息"; } Future<String> getStr2() async { await Future.delayed(Duration(seconds: 2)); // 模拟另一个耗时较长的操作 return "这是来自getStr2的消息"; } ``` 在这个案例里,当调用 `getName1()` 方法时,会依次打印出由两个模拟网络请求或其他长时间运行的任务所获取的信息,并最终显示 `'getName1'` 字符串[^3]。 #### 注意事项 - 如果在一个同步函数中尝试使用 `await` 将会导致编译错误;因此务必确保任何含有 `await` 表达式的上下文都已经被声明成 `async` 函数。 - 即使存在多处 `await` 调用,它们也会按照书写顺序逐一被执行完毕后再继续后续逻辑。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TDSSS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值