flutter中future microtask 的执行顺序是怎样的?

发布于 1周前 作者 caililin 来自 Flutter

Flutter 中 Future 和 Microtask 的执行顺序

在 Dart 中,Future 和微任务(microtasks)是异步编程的重要组成部分。它们的执行顺序由 Dart 的事件循环机制管理。以下是关于 Future 和微任务的执行顺序的详细说明,并附有示例代码。

事件循环概述

Dart 的事件循环主要有两个队列:

  1. 微任务队列(Microtask Queue):用于处理微任务,通常是由 Future 的回调和通过 scheduleMicrotask 创建的任务。
  2. 任务队列(Task Queue):用于处理常规的异步操作,如 Future.delayed、I/O 操作等。

执行顺序

  1. 创建 Future 和微任务

    • 当你创建一个 Future 时,相关的回调(如 .then().catchError())会被放入微任务队列。
    • 微任务的优先级高于任务队列中的任务。
  2. 执行顺序

    • 执行当前的同步代码:首先执行所有同步代码,直到没有更多的同步代码为止。
    • 微任务队列中的任务执行:一旦同步代码执行完毕,事件循环会执行微任务队列中的所有任务,直到队列为空。微任务的执行是逐个进行的,并且在处理完所有微任务后,事件循环才会转向任务队列。
    • 任务队列中的任务执行:微任务执行完毕后,事件循环将处理任务队列中的任务。只有在微任务队列为空时,事件循环才会开始处理任务队列。

示例代码

以下是一个示例,展示了 Future 和微任务的执行顺序:

void main() {
  print('Main start');

  // 创建一个 Future,并在其回调中添加微任务
  Future.value(42).then((_) {
    print('Future 1 callback (Microtask)');
    scheduleMicrotask(() {
      print('Microtask 2');
    });
  });

  // 使用 scheduleMicrotask 添加一个微任务
  scheduleMicrotask(() {
    print('Microtask 1');
  });

  // 创建一个延迟执行的 Future
  Future.delayed(Duration.zero, () {
    print('Future 2 (Task)');
  });

  print('Main end');
}

输出顺序分析

运行以上代码的输出顺序将是:

Main start
Main end
Microtask 1
Future 1 callback (Microtask)
Microtask 2
Future 2 (Task)
  • 主线程执行同步代码:首先执行 print('Main start')print('Main end')
  • 创建 Future 和微任务:在 main 函数中创建的 Future 和微任务会被添加到相应的队列。
  • 执行微任务:在主线程的所有同步代码执行完后,微任务队列中的所有微任务(Microtask 1Future 1 callback (Microtask) 中的 Microtask 2)会被依次执行。
  • 执行任务队列中的任务:在微任务队列为空后,事件循环会执行任务队列中的任务(Future 2 (Task))。

总结

  • 执行顺序:首先执行同步代码,然后执行微任务队列中的所有微任务,最后执行任务队列中的任务。
  • 优先级:微任务优先于任务执行,这意味着即使在创建了多个 Future,只要存在微任务,它们都会在任何任务执行之前被处理。

这种机制确保了 Dart 的异步操作能够高效且一致地处理,适合于构建流畅和响应迅速的用户界面。


更多关于flutter中future microtask 的执行顺序是怎样的?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于flutter中future microtask 的执行顺序是怎样的?的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,理解Futuremicrotask的执行顺序对于编写高效和可预测的代码至关重要。Flutter基于Dart语言,Dart的事件循环机制决定了Futuremicrotask的执行顺序。以下是对这一机制的详细解释,并附上相关代码示例。

Dart的事件循环机制

Dart的事件循环机制包括以下几个主要部分:

  1. 同步代码:首先执行当前调用栈中的所有同步代码。
  2. 微任务(Microtasks):执行所有已安排的微任务。微任务通常是由Dart.scheduleMicrotaskFuture.then等产生的。
  3. 事件队列(Event Queue):处理I/O事件、定时器(Timer)回调等。

Future 和 Microtask 的执行顺序

  • FutureFuture表示一个异步操作的结果。当你创建一个Future时,它的回调(如.then中的代码)会被放入微任务队列中,但实际的异步操作(如网络请求)会在事件队列中等待。
  • Microtask:微任务是由Dart.scheduleMicrotask直接调度的,或者由Future的回调(如.then.catchError等)隐式生成的。微任务会在当前同步代码执行完毕后立即执行,且在当前事件循环迭代中完成。

代码示例

以下是一个示例代码,展示了Futuremicrotask的执行顺序:

void main() async {
  print('Start');

  // 创建一个Future,它的回调会被放入微任务队列
  Future.delayed(Duration.zero, () {
    print('Future callback');
  });

  // 使用Dart.scheduleMicrotask直接调度一个微任务
  Dart.scheduleMicrotask(() {
    print('Microtask');
  });

  // 另一个Future,它的回调同样会被放入微任务队列
  Future.delayed(Duration.zero, () {
    print('Another Future callback');
  });

  // 同步代码执行完毕后,事件循环开始处理微任务队列
  await Future.delayed(Duration.zero); // 这是一个技巧,用于确保同步代码执行完毕

  // 注意:此时所有微任务已经执行完毕,因为Future.delayed(Duration.zero)本身不会阻塞事件循环,
  // 它只是将回调放入微任务队列,然后立即返回。

  print('End of main function');
}

输出结果

Start
Microtask
Future callback
Another Future callback
End of main function

解释

  1. Start:首先打印同步代码。
  2. Microtask:然后执行所有已安排的微任务。由于Dart.scheduleMicrotask直接调度了一个微任务,它首先被执行。
  3. Future callbackAnother Future callback:接着执行所有由Future.delayed(Duration.zero)生成的微任务回调。注意,尽管我们创建了两个这样的Future,但它们的回调都会在当前事件循环迭代中的微任务队列中依次执行。
  4. End of main function:最后,打印main函数的结束标记。

通过理解Dart的事件循环机制以及Futuremicrotask的执行顺序,你可以编写出更加高效和可预测的代码。

回到顶部