Flutter/Dart异步异常:await弹窗未等待返回值导致赋值null
问题分析与解决方案
核心问题:为什么_areYouSure会是null?
你的choiceAlert方法没有返回showDialog的执行结果!showDialog本身会返回一个Future<T?>对象,当你通过Navigator.pop(context, value)关闭弹窗时,这个Future会完成并返回你传入的value。但目前你的方法只是调用了showDialog,却没有把它的返回值return出去,所以await Alerts.choiceAlert(...)实际上是在等待一个void类型的结果,自然会得到null。
修复后的弹窗代码
只需要给choiceAlert方法加上return,返回showDialog的调用结果即可:
static Future<bool?> choiceAlert(BuildContext context, String _message) { AlertDialog alert = AlertDialog( title: Text('Alert!'), content: SingleChildScrollView( child: ListBody( children: <Widget>[Text(_message)], ), ), actions: <Widget>[ FlatButton( onPressed: () => Navigator.pop(context, true), child: Text('OK'), ), FlatButton( onPressed: () => Navigator.pop(context, false), child: Text('Cancel'), ), ], ); // 关键:返回showDialog的Future对象 return showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { return alert; }, ); }
调用代码的小优化(可选)
因为返回的是Future<bool?>,你可以用空安全的写法处理:
_discardSelectedAircraft() async { String _message = 'Are you sure. This is irreversible, you will loose all data.'; bool? _areYouSure = await Alerts.choiceAlert(context, _message); if (_areYouSure == true) { // 执行操作... } }
关于rootNavigator的疑问
首先要纠正一个小错误:你提到的Navigator.of(context, rootNavigator: true).pop(context, true)写法是有问题的——pop方法的第一个参数是context,第二个参数是返回结果,所以正确的写法应该是Navigator.of(context, rootNavigator: true).pop(true)(不要把context作为第二个参数传进去)。
那什么时候需要用rootNavigator: true?
- 当你的页面结构存在嵌套的Navigator(比如在TabBarView、Drawer或者自定义路由栈里),调用
showDialog时,弹窗可能会被嵌套的Navigator管理。此时用rootNavigator: true可以确保弹窗挂载到最顶层的Navigator上,关闭时也能正确回到顶层页面。 - 如果你的APP是单一Navigator结构(大多数简单APP都是这样),那么
Navigator.pop(context, true)就足够规范,不需要额外指定rootNavigator。
简单来说:如果你的弹窗关闭后出现异常(比如页面没有正确返回、残留弹窗),再考虑使用rootNavigator: true,否则保持原有写法即可。
内容的提问来源于stack exchange,提问作者Simon Lowther
相关产品推荐
相关产品推荐

