Dart异步与错误捕获

0 阅读2分钟

最清晰、最好记的异步来了!

一、总结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'); }