最清晰、最好记的异步来了!
一、总结Dart异步模型
Dart是单线程 + 事件循环(Event Loop)模型。
- Dart只有一个线程(虽然Dart中有事件队列里面分为事件队列跟微任务队列,但是本质是一个单线程语言,)
- 单线程中无论是单核cpu还是多核cpu Dart只占用一个核心,没有真正的“多线程并发”,靠的是事件循环实现异步
- async/await只是异步语法糖,dart底层是事件+队列
二、异步三要素
1、单线程(Main Thread)
所有代码(UI、业务、异步)都跑在这里。
2、事件循环
无限循环:不断从队列里拿到任务执行。
3、两个队列
- 微任务队列(MicroTask):优先级最高
- 事件队列(Event):网络、延迟、点击、Io都在这里
三、执行顺序
永不变口诀
同步->微任务->事件队列
四、await底层做了什么
Future<void> testAsync() async {
print('1. async 同步部分');
// await 已完成的 Future → Microtask Queue
await Future.value(null);
print('2. await value (Microtask)');
// await 延迟 Future → Event Queue
await Future.delayed(Duration.zero);
print('3. await delayed (Event Queue)');
}
1、遇到 await 时此方法中的后续代码才算是异步的
2、把后面的代码打包成一个微任务队列
3、立刻让出主线程
4、主线程继续干别的
5、等地啊异步操作完成
6、把打包的微任务放进队列
7、事件循环回来执行任务
五、错误捕获
1、最常用:try-catch捕获async/await错误
Future<void> doSomething() async {
try {
// 异步操作
await Future.delayed(Duration(seconds: 1));
// 可能出错的代码
throw Exception('网络请求失败');
} catch (e) {
// 捕获所有错误 print('捕获到错误: $e');
}
}
catch抓取报错
2、捕获Future.then()的错误
Future.delayed(Duration(seconds: 1))
.then((value) {
throw Exception('出错了');
})
.catchError((e) {
// 捕获错误
print('catchError: $e');
});
等待完成执行then,如有报错执行catchError。
3、精准捕获
try {
await something();
} on FormatException {
print('格式错误');
} on TimeoutException {
print('超时');
} catch (e) {
print('其他错误: $e'); }