Dart 异步函数 Async,await,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 特性 - 简书

猜你喜欢

转载自blog.csdn.net/TDSSS/article/details/129055921