如何解决Flutter onPressed异步功能不等待来自手肘/存储库的等待功能
我有一个注册按钮,可将http请求发送到我的API。请求完成后,我想离开注册页面。使用Bloc模式,我向Bloc中添加了一个事件以导航至登录页面,但是注册页面在将事件添加至Bloc之前并不等待http请求完成。
注册按钮代码:-
class _SignUpButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<SignUpCubit,SignUpState>(
buildWhen: (previous,current) => previous.status != current.status,builder: (context,state) {
return state.status.isSubmissionInProgress
? const CircularProgressIndicator()
: IconButton(
key: const Key('loginForm_continue_raisedButton'),onPressed: state.status.isValidated
? () async {
await context.bloc<SignUpCubit>().signUpFormSubmitted();
context.bloc<AuthenticationBloc>().add(AuthenticationUserChanged(User.empty));
}
: () => print('invalid'),icon: Icon(Icons.keyboard_arrow_right),color: Colors.white,iconSize: 40,);
},);
}
}
注册权限:-
part 'signup_state.dart';
class SignUpCubit extends Cubit<SignUpState> {
SignUpCubit(this._authenticationRepository)
: assert(_authenticationRepository != null),super(const SignUpState());
final AuthenticationRepository _authenticationRepository;
//irrelevant code omitted
Future<void> signUpFormSubmitted() async {
if (!state.status.isValidated) return;
emit(state.copyWith(status: FormzStatus.submissionInProgress));
try {
await _authenticationRepository.signUp(
name: state.name,password: state.password.value,mobile: state.mobile.value,village: state.village,email: state.email.value,pincode: state.pincode);
emit(state.copyWith(status: FormzStatus.submissionSuccess));
} on Exception {
emit(state.copyWith(status: FormzStatus.submissionFailure));
}
}
}
身份验证存储库:-
/// Thrown if during the sign up process if a failure occurs.
class SignUpFailure implements Exception {}
class AuthenticationRepository {
/// {@macro authentication_repository}
AuthenticationRepository({
FirebaseAuth firebaseAuth,GoogleSignIn googleSignIn,}) : _firebaseAuth = firebaseAuth ?? FirebaseAuth.instance,_googleSignIn = googleSignIn ?? GoogleSignIn.standard();
final FirebaseAuth _firebaseAuth;
final GoogleSignIn _googleSignIn;
/// Stream of [User] which will emit the current user when
/// the authentication state changes.
///
/// Emits [User.empty] if the user is not authenticated.
Stream<User> get user {
return _firebaseAuth.onAuthStateChanged.map((firebaseUser) {
return firebaseUser == null ? User.empty : firebaseUser.toUser;
});
}
//irrelevant code omitted
Future<void> signUp(
{@required String name,@required String password,@required String mobile,@required String village,@required String pincode,@required String email}) async {
assert(
name != null && mobile != null && village != null && pincode != null);
try {
if (email != '' && password != '') {
await _firebaseAuth.createUserWithEmailAndPassword(
email: email,password: password);
}
final params = {
'name': name,'phone': mobile,'village': village + '_' + pincode,'api': 't','login': 'NA'
};
Response res = await Dio().get(
"https://us-central1-greensat-9087a.cloudfunctions.net/addUser",queryParameters: params);
print(res.data);
} on Exception {
throw SignUpFailure();
}
}
}
身份验证集团:-
class AuthenticationBloc
extends Bloc<AuthenticationEvent,AuthenticationState> {
AuthenticationBloc({
@required AuthenticationRepository authenticationRepository,}) : assert(authenticationRepository != null),_authenticationRepository = authenticationRepository,super(const AuthenticationState.unknown()) {
_userSubscription = _authenticationRepository.user.listen(
(user) => add(AuthenticationUserChanged(user)),);
}
final AuthenticationRepository _authenticationRepository;
StreamSubscription<User> _userSubscription;
@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,) async* {
if (event is AuthenticationUserChanged) {
yield _mapAuthenticationUserChangedToState(event);
} else if (event is AuthenticationLogoutRequested) {
unawaited(_authenticationRepository.logOut());
} else if (event is AuthenticationOTPRequested) {
yield _mapAuthenticationUserOTPRequested(event);
} else if (event is AuthenticationSignupStarted) {
yield _mapAuthenticationUserSignupStarted(event);
}
}
@override
Future<void> close() {
_userSubscription?.cancel();
return super.close();
}
AuthenticationState _mapAuthenticationUserChangedToState(
AuthenticationUserChanged event,) {
print('user changed state');
print(event.user);
return event.user != User.empty
? AuthenticationState.authenticated(event.user)
: const AuthenticationState.unauthenticated();
}
AuthenticationState _mapAuthenticationUserOTPRequested(
AuthenticationOTPRequested event,) {
return const AuthenticationState.unauthenticatedOTP();
}
AuthenticationState _mapAuthenticationUserSignupStarted(
AuthenticationSignupStarted event,) {
return const AuthenticationState.signupStarted();
}
}
解决方法
你不能在 cubit 发射器函数中使用 async
错误:⛔️
void increment() async => emit(state+1)
正确:✅
void increment() => emit(state+1)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。