Flutter 三点一: Dart 异步 Future

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
相关推荐
旭日猎鹰4 小时前
Flutter踩坑记录(三)-- 更改入口执行文件
flutter
旭日猎鹰4 小时前
Flutter踩坑记录(一)debug运行生成的项目,不能手动点击运行
flutter
️ 邪神4 小时前
【Android、IOS、Flutter、鸿蒙、ReactNative 】自定义View
flutter·ios·鸿蒙·reactnative·anroid
比格丽巴格丽抱16 小时前
flutter项目苹果编译运行打包上线
flutter·ios
SoaringHeart16 小时前
Flutter进阶:基于 MLKit 的 OCR 文字识别
前端·flutter
AiFlutter20 小时前
Flutter通过 Coap发送组播
flutter
嘟嘟叽2 天前
初学 flutter 环境变量配置
flutter
iFlyCai2 天前
深入理解Flutter生命周期函数之StatefulWidget(一)
flutter·生命周期·dart·statefulwidget
sunly_2 天前
Flutter:photo_view图片预览功能
android·javascript·flutter
Summer不秃2 天前
Flutter中sqflite的使用案例
flutter