使用 bloc.emit 从块发出状态

hma*_*des 6 flutter bloc

我正在使用具有 BLoC 模式的库构建一个电话身份验证 ui (OTP) firebase_auth(对于这个 ui 来说有点过大,但整个项目都在 BLoC 中,所以)。我正在 BLoC 内处理身份验证,如下所示:


  @override
  Stream<PhoneAuthState> mapEventToState(PhoneAuthEvent event) async* {
    ....
    else if(event is PhoneNumberSubmittedEvent) yield* _handlePhoneNumberSubmittedEvent(event);
    ....
  }

  Stream<PhoneAuthState> _handlePhoneNumberSubmittedEvent(PhoneNumberSubmittedEvent event) async*{
      yield SendingCodeState();

      await Firebase.initializeApp();
      var firebaseAuth = FirebaseAuth.instance;

      await firebaseAuth.verifyPhoneNumber(
        phoneNumber: _buildPhoneNumber(),
        timeout: Duration(seconds: 0),
        verificationCompleted: (firebaseUser) {},
        codeAutoRetrievalTimeout: (String verificationId) {},


        // Relevant code

        codeSent: (id, [forceResendingToken]) =>
          emit(_codeSentState(id, forceResendingToken)),

        verificationFailed: (error) =>
          emit(_verificationFailedState(error)),
      );
  }

Run Code Online (Sandbox Code Playgroud)

_codeSentState因为 my和函数的结果_verificationFailedState无法从方法内部产生handlePhoneNumberSubmittedEvent,所以我使用了emit(实际上工作正常)。

然而,当我查看 BLoC 文档时,我发现是emit@protected并且文档指出:

[emit] 决不应该在测试之外使用。

所以我有三个问题:

  1. 为什么不应该emit在测试之外使用?
  2. 有替代方案吗emit?(除了响应中的事件而屈服mapEventToState
  3. 有没有办法将yield函数的结果作为参数传递给方法/构造函数调用?(就我而言,有没有办法分别在 和内调用和/或yield的结果?)_codeSentState_verificationFailedStatefirebaseAuth.verifyPhoneNumber.codeSentfirebaseAuth.verifyPhoneNumber.verificationFailed

hma*_*des 4

flutter_bloc8.0.0版本中,这个问题得到了解决。该方法mapEventToState被替换为更有效地on<Event>响应事件。on方法提供一个emitter作为其回调的参数,可用于根据需要发出状态。也就是说,我在OP中提到的代码现在可以写成如下

// constructor
MyBloc() : super(MyInitialState) {
  on<PhoneNumberSubmittedEvent>((event, emit) async {
      emit(SendingCodeState());

      await Firebase.initializeApp();
      var firebaseAuth = FirebaseAuth.instance;

      await firebaseAuth.verifyPhoneNumber(
        phoneNumber: _buildPhoneNumber(),
        timeout: Duration(seconds: 0),
        verificationCompleted: (firebaseUser) {},
        codeAutoRetrievalTimeout: (String verificationId) {},

        codeSent: (id, [forceResendingToken]) =>
          emit(_codeSentState(id, forceResendingToken)),

        verificationFailed: (error) =>
          emit(_verificationFailedState(error)),
      );
  });
}
Run Code Online (Sandbox Code Playgroud)