Flutter登录场景:如何在catchError执行后终止Future的then函数?
解决方案
方法一:用async/await重构代码(推荐)
这种写法能让异步逻辑更直观,出错时直接中断流程,避免跳转逻辑被误触发。修改后的代码如下:
void signIn() async { setState(() { _isLoading = true; }); final isValid = _formKey.currentState!.validate(); if (!isValid) { setState(() { _isLoading = false; }); return; } try { // 等待登录请求完成 await Provider.of<Authorization>(context, listen: false) .loginUser( _emailController.text.trim(), _passwordController.text.trim(), ); // 只有登录成功才走到这里 setState(() { _isLoading = false; }); Navigator.push( context, MaterialPageRoute( builder: ((context) => const HomeScreen()), ), ); } catch (error) { // 登录出错时处理提示 const snackBar = SnackBar( backgroundColor: Colors.red, content: Text("An error occured please try again."), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); setState(() { _isLoading = false; }); } }
方法二:修改原有的链式调用
如果不想重构代码,只需在catchError里重新抛出错误,就能中断后续的then执行:
void signIn() { setState(() { _isLoading = true; }); final isValid = _formKey.currentState!.validate(); if (isValid == false) { setState(() { _isLoading = false; }); return; } else { setState(() { _isLoading = true; }); Provider.of<Authorization>(context, listen: false) .loginUser( _emailController.text.trim(), _passwordController.text.trim(), ) .catchError((error) { const snackBar = SnackBar( backgroundColor: Colors.red, content: Text("An error occured please try again."), ); ScaffoldMessenger.of(context).showSnackBar(snackBar); // 重新抛出错误,让Future保持失败状态,阻止then执行 throw error; }).then((_) { setState(() { _isLoading = false; }); Navigator.push( context, MaterialPageRoute( builder: ((context) => const HomeScreen()), ), ); }); } }
内容的提问来源于stack exchange,提问作者Ariyo
相关产品推荐
相关产品推荐

