【问题标题】:Flutter Bloc Error : emit was called after an event handler completed normally - between two functionsFlutter Bloc 错误:在事件处理程序正常完成后调用了发射 - 在两个函数之间
【发布时间】:2022-01-26 00:20:36
【问题描述】:

我有以下问题...

在事件处理程序正常完成后调用emit。这是 通常是由于事件处理程序中未曾等待的未来。请做出来 确保使用事件处理程序等待所有异步操作并使用 在调用 emit() 之前的异步操作之后的 emit.isDone 确保事件处理程序尚未完成。

不好 on((事件,发射){ future.whenComplete(() => 发射(...)); });

GOOD on((event, emit) async { 等待future.whenComplete(() => emit(...)); }); )

发生的情况是,在一个名为_onLogIn的函数中,如果用户更改了语言,它会从那里转到块内的另一个函数,这两个函数不相互依赖,我表示每个函数在应用程序的不同页面中被调用,但仍然_onLogIn检查_onChangeLanguage函数。

  UserBloc({this.usecases}) : super(UserInitial()) {
    on<LogInEvent>(_onLogIn);
    on<ChangeLanguageEvent>(_onChangeLanguage);
  }

_onLogIn 函数:

void _onLogIn(
    LogInEvent event,
    Emitter<StateA> emit,
  ) async {

    emit(UserLoading());

    final userOrFailure = await services.logIn(
      x: event.x,
      y: event.y,
    );

    await userOrFailure.fold((user) async {

        /// If the user is logging in for the first time and does not
        /// have a preferred language.
        if (user.preferredLanguage == null) {
          emit(UserSuccess());

          emit(UserAlreadyLogged(connectedUser));

        } else {
          /// An ChangeLanguageEvent object
          ChangeLanguageEvent event = ChangeLanguageEvent(
            user.preferredLanguage,
            user.someId,
          );

          /// Call the other function in the same bloc
          this._onChangeLanguage(
            event,
            emit,
            isFromLogin: true,
          );
        }
      
    }, (failure) {
      emit(UserError(failure.message));
    });
  }

_onChangeLanguage 函数:

  void _onChangeLanguage(
    ChangeLanguageEvent event,
    Emitter<StateA> emit, {
    bool isFromLogin = false,
  }) async {

    final successOrFailure = await services.updateLanguage(
      event.language,
      event.someId,
    );

    await successOrFailure.fold( // ! HERE THE ERROR WHEN I LOG IN; but when i changed the language from the application i don't have an error
      (language) async {

        emit(ChangeAppLanguage(language));

        final sessionOrFailure = await services.getSession();

        sessionOrFailure.fold(
          (session) {
            /// I need this condition to know if the language comes from login
            if (isFromLogin) {
              emit(UserSuccess());
            }
            emit(UserAlreadyLogged(session));
          },
          (failure) => emit(UserError(failure.message)),
        );
      },
      (failure) {
        emit(UserError(failure.message));
      },
    );
  }

知道为什么吗?谢谢

【问题讨论】:

  • 我假设 _onLogIn 在一些 on&lt;...&gt; 方法中被调用,对吧?如果是这样,您的 emit 似乎在 on 方法完成后被调用 - 这很可能是因为您的 fold 方法没有等待它们的 async 回调
  • @pskink 是的,两个,我都在描述中添加了你知道我该如何修复它吗?

标签: flutter dart async-await bloc dartz


【解决方案1】:
void _onChangeLanguage(
    ChangeLanguageEvent event,
    Emitter<StateA> emit, {
    bool isFromLogin = false,
  }) async

这应该是一个主要危险信号。标记为async 的调用,但未返回Future&lt;&gt;。没有办法,调用者可能会等待这个调用。甚至知道他们应该等待这个电话。

让它返回一个正确的Future&lt;void&gt; 而不仅仅是void,你的集团应该接受它并正确地等待呼叫。

对此甚至有一条 linter 规则:avoid_void_async。你关掉你的linter了吗?不要那样做。打开你的 linter 并聆听它。你的其他函数也有同样的问题。

【讨论】:

  • 这对我很有帮助,谢谢!在调用其他函数之前加上“await”。
猜你喜欢
  • 1970-01-01
  • 2022-01-10
  • 2022-12-15
  • 1970-01-01
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2020-03-23
  • 2020-11-12
相关资源
最近更新 更多