Flutter 三点一: Dart 异步 Future

本文详细介绍了Dart中的异步编程,特别是Future和async/await的使用,以及EventLoop、EventQueue和MicroTaskQueue的工作原理。还讨论了如何利用链式调用和处理异步异常。
摘要由CSDN通过智能技术生成

Dart的异步

  • Future
  • async 和 await
  • Future相对于async, await的最大优势在于它提供了强大的链式调用
事件循环EventLoop
  • Dart EventLoop 有两个列队 :
    • 事件列队 Event Queue
      • IO
      • 手势
      • 绘制
      • 定时器
      • Stream流
      • Future
    • 微任务列队 MicroTask Queue
      • 微任务执行非常短暂
      • 通过scheduleMicroTask 调度
      • 比事件列队优先级高
Future
void main(){
  print("${DateTime.now().second}开始登录");  //执行
  var loginResult = login();
  print("${DateTime.now().second}登录已调用"); //执行
  
  //获取异步结果
  loginResult.then((value) => print(value));
  loginResult.then((value){
    print(value);
  });
}

Future<String> login(){
  return Future((){
    print("${DateTime.now().second}登录中..."); //执行
    sleep(Duration(seconds:5));
    print("${DateTime.now().second}登录成功");  //5s后执行
    return "登录成功,即将开启新的宇宙";
  });
}

运行结果

1开始登录
1登录已调用
1登录中...
6登录成功
登录成功,即将开启新的宇宙
登录成功,即将开启新的宇宙
  • 异步抛出异常 即 执行完成回调
void main() {
  login("username", "password")
      .then((value) => print(value))
      .catchError((error) => print(error))
      .whenComplete(() => print("登录结束"));


  login("", "password")
      .then((value) => print(value))
      .catchError((error) => print(error))
      .whenComplete(() => print("登录结束"));

  login("张三", "password")
      .then((value) => print(value))
      .catchError((error) => print(error))
      .whenComplete(() => print("登录结束"));

}

Future<String> login(String username, String password) {
  return Future(() {
    print("${DateTime.now().second}登录中..."); //执行
    if (username.isEmpty || password.isEmpty) {
      throw HttpException("${DateTime.now().second}账号或密码不能为空!");
    }
    sleep(Duration(seconds: 5));

    if (username == "张三"){
      throw HttpException("${DateTime.now().second}您已被拉入黑暗深渊!");
    }
    print("${DateTime.now().second}登录成功"); //5s后执行
    return "登录成功,即将开启新的宇宙";
  });
}

运行结果

20登录中...
25登录成功
登录成功,即将开启新的宇宙  
登录结束

25登录中...
HttpException: 25账号或密码不能为空!  //直接抛出异常
登录结束

25登录中...
HttpException: 30您已被拉入黑暗深渊!  //5秒后
登录结束

  • Future 可以链式调用
    登录流程
void main() {
    Future.value(["username","password"])
        .then((value){
            login(value[0],value[1]);
            print("${DateTime.now().millisecondsSinceEpoch} >> 登录中...");
            sleep(Duration(seconds: 5));
            return '{"id": 10001,"name": "John","classGrade": "三年二班","birthday": "2005-12-12 12:12:12", "age": 30}';})
        .then((value){
            return value;
    })
        .then((value){
            print("${DateTime.now().millisecondsSinceEpoch} >> "+value);  //json

            var json = jsonDecode(value);
            int id = json['id'];
            getUserInfo(id);
            print("${DateTime.now().millisecondsSinceEpoch} >> 获取用户信息...");
            sleep(Duration(seconds: 5));
            return "成功,缓存数据,跳转首页";
    })
        .catchError((value){})
        .whenComplete((){
       print("登录流程结束!");
    });
}

login(String username,String password){
    print("${DateTime.now().millisecondsSinceEpoch} >> ${username}请求登录!");
}
getUserInfo(int id){
    print("${DateTime.now().millisecondsSinceEpoch} >> ${id}获取用户信息!");
}

结果:

1703559427736 >> username请求登录!
1703559427737 >> 登录中...
1703559432743 >> {"id": 10001,"name": "John","classGrade": "三年二班","birthday": "2005-12-12 12:12:12", "age": 30}
1703559432758 >> 10001获取用户信息!
1703559432758 >> 获取用户信息...
登录流程结束!

Future其他函数

  • Future.value Future指定为某个指定值
  • Future.error 执行错误回调
  • Future.delayed 延时执行
  • Future.wait 等待其他异步执行完成后执行
void main() {
    print("${DateTime.now().millisecondsSinceEpoch} >> 开始执行");
    var future1 = Future.value("aaaaaa").then((value){
        sleep(Duration(seconds: 2));//等待2s
        print("${DateTime.now().millisecondsSinceEpoch} >> "+value);
    });
    var future2 = Future.error(HttpException("请求失败!")).catchError((error)=> print(error));
    var future3 = Future.delayed(Duration(seconds: 5),(){return "${DateTime.now().millisecondsSinceEpoch} >> 回调函数!";})
    .then((value) => print(value));  //5s后输入结果
    Future.wait([future2,future1]).then((value) => print("${DateTime.now().millisecondsSinceEpoch} >>  等待 future2 future1 执行完成才执行"));
    Future.wait([future1,future2]).then((value) => print("${DateTime.now().millisecondsSinceEpoch} >>  等待 future1 future2执行完成才执行"));
}

执行结果

1703560731843 >> 开始执行
1703560733860 >> aaaaaa   //2s后执行 future1 
HttpException: 请求失败!
1703560733869 >>  等待 future2 future1 执行完成才执行   //等待future2,future1执行完才执行
1703560733869 >>  等待 future1 future2执行完成才执行    //等待future2,future1执行完才执行
1703560736857 >> 回调函数!    // 开始执行后5s才执行 future3 的结果
  • Future.doWhile 执行异步操作的循环,打断条件为 不满足return的判断
void main() {
    print("开始执行");
    var a = 0;
    Future.doWhile((){
        a++;
        print(a);
        return a < 5;
    });
    print("结束执行");
}

结果 看起来好像是主线程阻塞执行

开始执行
1
2
3
4
5
结束执行 加上async 

异步执行

void main() {
    print("开始执行");
    var a = 0;
    Future.doWhile(() async {
        a++;
        print(a);
        return a < 5;
    });
    print("结束执行");
}

结果:

开始执行
1
结束执行
2
3
4
5
  • Future.forEach 异步遍历集合
    print("开始执行");
    Future.forEach(['a','b','c','d','e'], (element){print(element);});
    print("结束执行");
开始执行
a
b
c
d
e
结束执行
void main() {
    print("开始执行");
    Future.forEach(['a','b','c','d','e'], (element) async {print(element);});
    print("结束执行");
}

结果:

开始执行
a
结束执行
b
c
d
e
  • Future.sync 创建一个同步的Future对象 但是返回的future对象依然是异步的
void main() {
    print("开始执行");
    Future.sync((){
        print("sync");
        return "aaa";
    }).then((value) => print(value));
    print("结束执行");
}

运行结果:

开始执行
sync
结束执行
aaa
  • Future.microtask
    Future一般会把事件发送到Event Queue中
    但是Future.microtask 会把事件加入到Microtask Queue 轻便且速度快的微任务
    microtask队列的优先级是比event队列高
void main() {
    print("开始执行");
    Future((){
       print("nomal future");
    });
    Future.microtask((){
        print("microtask future");
    });
    print("结束执行");
}

结果:

开始执行
结束执行
microtask future
nomal future
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值