0

我有一个奇怪的问题,我花了几个小时。我有一个 bloc 文件,我在其中使用 dartZ 来更轻松地维护错误。当我像这样使用 bloc 时:

  NumberTriviaBloc({required this.getConcreteNumberTrivia}) : super(Empty()) {
    on<GetTriviaForConcreteNumber>((event, emit) async {
      final inputEither =
          inputConverter.stringToUnsignedInteger(event.numberString);

      inputEither.fold((failure) => emit(Error(message: invalidInputMessage)),
          (integer) async {
        emit(Loading());
        final failureOrTrivia =
            await getConcreteNumberTrivia(Params(number: integer));
        emit(
          failureOrTrivia.fold(
            (failure) => Error(message: _mapFailureToMessage(failure)),
            (trivia) => Loaded(trivia: trivia),
          ),
        );
      });
    });
  }

我收到错误消息,说我没有等待一些 Future - https://pastebin.com/FWTFKYVH但这似乎不是真的,因为我只有一个 getConcreteNumberTrivia返回 Future 的函数,它正在等待中。

但是当我被切断最后一次发射以分离这样的功能时:

  void _eitherLoadedOrErrorState(
    Either<Failure, NumberTrivia> failureOrTrivia,
  ) {
    emit(
      failureOrTrivia.fold(
        (failure) => Error(message: _mapFailureToMessage(failure)),
        (trivia) => Loaded(trivia: trivia),
      ),
    );
  }

代码开始正常工作。我不明白,我只是将代码移动到 void 函数,它没有做任何额外的事情,有人可以解释我为什么吗?

4

2 回答 2

1

让我们去掉一些开销,看看细节:

inputEither.fold((failure) { /*...*/ }, (integer) async { /*...*/ });

查看fold方法,它返回B,这B是它的两个函数的共同返回值。您的第一个函数返回void,您的第二个函数在Future<void>您标记后返回async。所以这两个函数的共同返回值可能是FutureOr<void>. 那应该被await编辑。

await inputEither.fold((failure) { /*...*/ }, (integer) async { /*...*/  });

现在这些是技术细节。一些个人观察:函数式编程旨在使代码更易于结构化和更易于阅读。对我来说,你的比它的 OOP 等价物更难阅读。我不认为这是一件好事。有多层折叠让人难以阅读(对我来说,谁不习惯)。如果您不使用 lambda 函数,而是编写具有真实返回类型和参数的真实函数,它可能会变得更容易阅读、更容易处理和理解。然后你会亲眼看到我刚才解释的内容。

于 2022-01-25T13:30:37.137 回答
0

nvoigt 解释了为什么你得到一个错误。提取方法后没有出现错误的原因是您没有提取emit参数。根据文档emit,您提取的方法中的 in 是指Bloc类的emit方法,该方法“仅供内部使用,绝不应在测试之外直接调用”。

于 2022-01-25T17:01:56.550 回答