如何在不使用async函数的if条件中使用Future<bool>函数结果?
Flutter异步判断用户会员状态,无需await控制组件显示问题
问题说明
我是Flutter新手,编写了返回Future<bool>类型的isUserPremium函数,用于检查用户是否为Premium会员,代码如下:
Future<bool> isUserPremium() async { final FirebaseAuth _auth = FirebaseAuth.instance; final User user = _auth.currentUser; if (user != null) { final DocumentSnapshot snapshot = await FirebaseFirestore.instance .collection('users') .doc(user.uid) .get(); final bool isPremium = snapshot['userType'] == 'UserType.premium'; return isPremium; } else { return false; } }
我希望在以下代码的if条件中,用该函数的结果控制星标Icon的显示隐藏,但不想在build方法中使用async/await:
child: Stack( children: [ ClipOval( child: Material( color: Colors.transparent, child: FadeInImage.assetNetwork( placeholder: 'assets/images/gif_loading.gif', image: widget.imageUrl, fit: BoxFit.cover, width: 200, height: 200, ), ), ), // 问题:不想在这里用async或await,该怎么做? if (await profilProvider.isUserPremium()) Positioned( top: 10, right: 15, child: Icon( Icons.star, size: 40, color: Colors.red, ), ), ], ),
我尝试使用didChangeDependencies函数实现,但没有效果,代码如下:
var _isPremium = false; var _isInit = true; @override void didChangeDependencies() async { if (_isInit) { _isPremium = false; final profilProivder = Provider.of<Profil>(context, listen: false); _isPremium = await profilProivder.isUserPremium(); } super.didChangeDependencies(); _isInit = false; }
问题原因
didChangeDependencies是同步生命周期方法,标记为async后,异步操作会脱离生命周期流程,_isInit = false可能在异步请求完成前就执行,导致后续无法重新触发逻辑。- 即使成功获取到
_isPremium的值,没有触发组件重建(比如调用setState),UI不会更新,所以看不到星标显示。
解决方案
方案1:StatefulWidget配合setState更新状态
将异步逻辑放到独立的初始化方法中,获取结果后调用setState触发UI重建:
var _isPremium = false; var _isInit = true; @override void initState() { super.initState(); _fetchPremiumStatus(); } // 单独的异步方法处理会员状态检查 void _fetchPremiumStatus() async { final profilProvider = Provider.of<Profil>(context, listen: false); _isPremium = await profilProvider.isUserPremium(); setState(() {}); // 触发UI更新 } // build方法中直接使用_isPremium判断 child: Stack( children: [ // 原有头像组件... if (_isPremium) Positioned( top: 10, right: 15, child: Icon( Icons.star, size: 40, color: Colors.red, ), ), ], ),
方案2:让Provider管理会员状态(更推荐)
把会员状态的检查和维护逻辑移到Provider内部,通过notifyListeners()自动通知UI更新,避免手动调用setState:
首先修改Profil Provider:
class Profil extends ChangeNotifier { bool _isPremium = false; bool get isPremium => _isPremium; // 在Provider内部实现会员状态检查 Future<void> checkUserPremium() async { final FirebaseAuth _auth = FirebaseAuth.instance; final User? user = _auth.currentUser; if (user != null) { final DocumentSnapshot snapshot = await FirebaseFirestore.instance .collection('users') .doc(user.uid) .get(); _isPremium = snapshot['userType'] == 'UserType.premium'; } else { _isPremium = false; } notifyListeners(); // 通知所有监听的UI组件更新 } }
然后在页面中初始化并监听状态:
@override void initState() { super.initState(); // 初始化时触发会员状态检查 Provider.of<Profil>(context, listen: false).checkUserPremium(); } // build方法中直接监听Provider的isPremium状态 child: Stack( children: [ // 原有头像组件... if (Provider.of<Profil>(context).isPremium) Positioned( top: 10, right: 15, child: Icon( Icons.star, size: 40, color: Colors.red, ), ), ], ),
内容的提问来源于stack exchange,提问作者Ayham
相关产品推荐
相关产品推荐

