dart
@override
void initState() {
super.initState();
// 这里没有使用微任务,而是用的0帧
Future.delayed(Duration.zero, () {
dynamic obj = ModalRoute.of(context)?.settings.arguments;
if (obj != null) {
classId = obj["classId"];
title = obj["title"];
needPop = true;
} else {
classId = widget.classId;
title = widget.title;
}
loadData(update: true);
});
}
dart
// 使用微任务
String _routeGetArguments = "";
@override
void initState() {
super.initState();
/// 异步微任务接收
Future.microtask((){
if(ModalRoute.of(context) != null){
Map<String,dynamic> params = ModalRoute.of(context)!.settings.arguments as Map<String,dynamic>;
_routeGetArguments = params["index"].toString();
///更新视图,要不然UI中不会显示出来,记住一定要写
setState(() {});
} else {
print("获取不到路由参数");
}
});
}
在Flutter中,这里使用Future.delayed(Duration.zero)而不是微任务,主要是出于构建上下文生命周期的考虑。
为什么使用 Future.delayed(Duration.zero)
-
避免在build期间访问路由参数
- 在
initState()中,widget尚未完成首次构建 - 直接访问
ModalRoute.of(context)可能会因为context还未完全建立而返回null Future.delayed(Duration.zero)将执行推迟到当前帧构建完成后
- 在
-
确保context可用
dart// 这样可能无法正确获取路由参数 dynamic obj = ModalRoute.of(context)?.settings.arguments; // 可能为null // 使用延迟确保context已准备好 Future.delayed(Duration.zero, () { dynamic obj = ModalRoute.of(context)?.settings.arguments; // 更安全 });
微任务 vs 延迟零秒的区别
- 微任务 (
scheduleMicrotask):在当前事件循环的微任务队列中执行,比UI渲染优先级更高 - Future.delayed(Duration.zero):在下一个事件循环中执行,确保当前widget构建过程已完成
为什么不是微任务
在这个场景下,使用微任务可能过早 执行,因为widget可能还在构建过程中。而Future.delayed(Duration.zero)确保在widget完全构建后 再执行参数获取,这样ModalRoute.of(context)能够正确获取到路由参数。
这种方式是Flutter中处理"需要等待widget构建完成后再执行"的常见模式。