【发布时间】:2021-08-06 16:10:14
【问题描述】:
我有一个注册按钮,它向我的 API 发送一个 http 请求。我想在请求完成后离开注册页面。使用 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();
}
}
【问题讨论】:
标签: android flutter asynchronous async-await