Flutter 假异步的实现示例

就像 android 有 handle 一样,消息队列这东西好像还真是系统必备,Flutter 也有自己的消息队列,只不过队列直接封装在了 Dart 的线程类型 Isolate 里面了,不过 Flutter 还是提供了 Futrue 这个 API 来专门来操作各种消息,以及实现基于消息队列的假异步

Flutter 的“异步”机制

这里的异步是加了引号的,可见此异步非真异步,而是假异步。Flutter 的 异步 不是开新线程,而是往所属线程的 消息队列 中添加任务,当然大家也可以按上文那样自己展开真异步操作

Flutter 对代码分2类: 同步代码和异步代码

  • 同步代码:传统一行行写下来,一行行执行的代码
  • 异步代码:通过 Future API 把任务添加到 Isolate 所属消息队列执行的伪异步
  • 执行顺序:先运行同步代码,再运行异步代码

为啥,很明显啊,异步代码是往消息队列里添加任务,那肯定得等现在的代码运行完了,线程有空闲了才能开始执行消息队列里的任务呀~

举个例子:

void test() {
  print("AA");
  Future(() => print("Futrue"));
  print("BB");
}
~~~~~~~~~~~log~~~~~~~~~~~~~
I/flutter (10064): AA
I/flutter (10064): BB
I/flutter (10064): Futrue

print("Futrue")) 任务等到最后才执行的...

Flutter 提供了往 消息队列 添加数据的 API: Future

往 MicroTask 队列添加任务

scheduleMicrotask((){
 // ...code goes here...
}); 

new Future.microtask((){
  // ...code goes here...
});

往 Event 队列添加任务

new Future(() {
 // ...code goes here...
});

Future 的基本使用

Future 对象是 Flutter 专门提供的,基于消息队列实现异步的类,Future 对象会把自身当做一个任务添加到消息队列中去排队执行

Future 对象接受的是一个函数,就是要执行的任务,用 () => ... 简写也是可以的

void task() {
  print("AA");
}

var futrue = Future(task);

创建 Future 任务方式:

  • Future()
  • Future.microtask()
  • Future.sync() - 同步任务
  • Future.value()
  • Future.delayed() - 延迟xx时间添加任务
  • Future.error() - 错误处理

我们来看几个代表性的:

Future.sync() - 阻塞任务,会阻塞当前代码,sync 的任务执行完了,代码才能走到下一行

void test() {
  print("AA");
  Future.sync(() => print("Futrue"));
  print("BB");
}
~~~~~~~~~~~~log~~~~~~~~~~~~~~
I/flutter (10573): AA
I/flutter (10573): Futrue
I/flutter (10573): BB

Future.delayed() - 延迟任务,指定xx时间后把任务添加到消息队列,要是消息队列前面有人执行的时间太长了,那么执行时间点就不能把握了,这点大家要知道

void test() {
  print("AA");
  Future.delayed(Duration(milliseconds: 500),() => print("Futrue"));
  print("BB");
}
~~~~~~~~~~~~log~~~~~~~~~~~~~~
I/flutter (10573): AA
I/flutter (10573): BB
I/flutter (10573): Futrue

Future 的链式调用

Future 也支持链式调用的,在 API 使用上也是很灵活的,提供了下面的选择给大家

.then - 在 Future 执行完后执行,相当于一个 callback,而不是重新创建了一个 Future

 Future.delayed(Duration(seconds: 1),(){
   print(("AAA"));
   return "AA";
  }).then((value){
   print(value);
  });

.catchError - future 不管在任何位置发生了错误,都会立即执行 catchError

  Future.delayed(Duration(seconds: 1),(){
   throw Exception("AAA");
  }).then((value){
   print(value);
  }).catchError((error){
   print(error);
  });

.whenComplete - 不管是否发生异常,在执行完成后,都会执行该方法

 Future.delayed(Duration(seconds: 1),() {
   throw Exception("AAA");
  }).then((value) {
   print(value);
  }).catchError((error) {
   print(error);
  }).whenComplete(() {
   print("complete...");
  });

.wait - 可以等待所有的 future 都执行完毕再走 then 的方法

Future.wait([
   // 2秒后返回结果
   Future.delayed(new Duration(seconds: 2),() {
    return "hello";
   }),// 4秒后返回结果
   Future.delayed(new Duration(seconds: 4),() {
    return " world";
   })
  ]).then((results) {
   print(results[0] + results[1]);
  }).catchError((e) {
   print(e);
  });

大家想想啊

Futrue()
  .then()
  .then()
  ...

这样的链式写法不就是标准的去 callback 回调地狱的方式嘛

async/await 关键字

async/await 这组关键字是系统提供的另一种实现 异步 任务的 API, async/await 底层还是用 Futrue 实现的,从使用上看是对 Futrue 的简化,本质上还是基于 消息队列 实现的异步,是 假异步 ,和 Isoalte 是不一样的

async/await 的特点就是: 成对出现

  • async - 修饰方法,用 async 声明的方法都是耗时的
  • await - 调用 async 方法时使用,也可以在 async 方法内部是适用,await 表示阻塞,下面的任务必须等 await 调用的方法执行完之后才能执行

比如这样:

 anysncTest() async {
  print("async 休眠 start...");
  sleep(Duration(seconds: 1));
  print("async 休眠 end...");
 }

await anysncTest();

本质上 await 调用的方法其实是把这个方法包装到 Futrue 中去消息队列里执行,只不过是: Future.sync() 阻塞式的 Future 任务

这 async 在布局中也是可以直接用的

class TestWidgetState extends State<TestWidget> {
 int _count = 0;

 @override
 Widget build(BuildContext context) {
  return Material(
    FlatButton(
      onPressed: () async {
        _count = countEven(1000000000);
        setState(() {});
      },child: Text(
        _count.toString(),)),);
 }

async/await 是阻塞式的函数

实验1:

 // 这是异步任务代码
 aaa() async{
  print("main1...");
  await anysncTest();
  print("main2...");
  print("main3...");
 }

 anysncTest() async {
  print("async 休眠 start...");
  sleep(Duration(seconds: 1));
  print("async 休眠 end...");
 }

 // 点击按钮去执行
  Widget build(BuildContext context) {
  return RaisedButton(
   child: (Text("click!")),onPressed: () async {
    await aaa();
   },);
 }

以上是来客网为你收集整理的Flutter 假异步的实现示例全部内容,希望文章能够帮你解决Flutter 假异步的实现示例所遇到的程序开发问题。

如果觉得来客网网站内容还不错,欢迎将来客网网站推荐给程序员好友。