Flutter BLoC 模式 Future<T>.then 不是基于存储库网络结果触发

Flutter BLoC pattern Future<T>.then is not triggers base on repository network results

我是 Flutter 和 BLoC 模式的新手。我已经使用 BLoC 模式实现了一个简单的 get 网络调用。 流动存储库调用根据提供给网络调用的输入参数获取酒店方法。

class HotelSearchRepository {
  
  Future<Resource<List<Hotel>>> getHotelSearchResults(
      HashMap<String, Object> requestData) async {

    try {

      final response = await Network().getHotelSearchResults(requestData);
      final data  = HotelResponse.fromJson(jsonDecode(response.data));

      if (data.status) {
        final hotels = data.hotelsArray.hotels;
        final hotelSearchData = List<Hotel>();

        hotels.forEach((hotel) {
          final hotelImage = hotel.hotelImage;
          final hotelTripAdvisorRatingUrl = hotel.hotelTripAdvisorRatingUrl;
          final promoDescription = hotel.promoDescription;
          final hotelName = hotel.hotelName;
          final hotelAddress = hotel.hotelAddress1;
          final hotelRatings = hotel.hotelStar;
          final isBeadInBreakfirstAvaiable =
              hotel.hotelBoardBasis != null && hotel.hotelBoardBasis == "BB";
          final extraperks = hotel.hotelRoom;
          final oldPrice = hotel.hotelBaserate;
          final currentPrice = hotel.hotelPrice;

          var currencyNumberFormatter = NumberFormat.currency(
              locale: "si", customPattern: "###,###,###,###");

          final hotelItem = Hotel(
              name: hotelName,
              address: hotelAddress,
              rating: double.parse(hotelRatings),
              image: hotelImage,
              tripAdviserImageLink: hotelTripAdvisorRatingUrl,
              promotionDescription: promoDescription,
              isBeadInBreakfirstAvaiable: isBeadInBreakfirstAvaiable,
              extraperks: extraperks,
              oldPrice: currencyNumberFormatter.format(oldPrice),
              currentPrice: currencyNumberFormatter.format(currentPrice));

          hotelSearchData.add(hotelItem);
        });

        return Resource(DataRetrieveStatus.SUCCESS, hotelSearchData);

      } else {

        var displayMessage = DisplayMessage(
            title: "Response Error", description: data.errorMessage);
            
        return Resource.displayConstructor(
            DataRetrieveStatus.RESPONSE_ERROR, displayMessage);

      }

    } on DioError catch (e) {

      switch (e.type) {
        case DioErrorType.CONNECT_TIMEOUT:
        case DioErrorType.SEND_TIMEOUT:
        case DioErrorType.RECEIVE_TIMEOUT:
        case DioErrorType.RESPONSE:

        var displayMessage = DisplayMessage(
              title: "Connection Error",description:  "Application fiald top connect with the server");

          return Resource.displayConstructor(
              DataRetrieveStatus.CONNECTION_ERROR, displayMessage);

          break;
        case DioErrorType.DEFAULT:

          var displayMessage = DisplayMessage(
              title: "Processing Error", description:"Something went wrong. Please try again later.");

          return Resource.displayConstructor(
              DataRetrieveStatus.PROCESSING_ERROR, displayMessage);

          break;
        case DioErrorType.CANCEL:
          break;
      }

    }
  }
}

我正在使用 Stetho 监控网络调用,但我得到的结果是状态为假。我放置了一个调试点以确保它命中 return 语句。虽然它在我的 DataretrieveBloc 中调用 return Resource.displayConstructor(DataRetrieveStatus.RESPONSE_ERROR, displayMessage); 行代码,但不会触发。

class DataretrieveBloc extends Bloc<DataretrieveEvent, DataretrieveState> {
  final HotelSearchRepository hotelSearchRipository;

  DataretrieveBloc(this.hotelSearchRipository);

  @override
  DataretrieveState get initialState => DataretrieveInitial();

  @override
  Stream<DataretrieveState> mapEventToState(DataretrieveEvent event) async* {
    yield HotelLoading();

    if (event is GetHotels) {
      HashMap<String, Object> requestData = HashMap();
      requestData["check_in"] = event.checkInDate;
      requestData["check_out"] = event.checkOutDate;
      requestData["city_full_str"] = event.city;
      requestData["sgen"] = event.sgen;
      requestData["page"] = event.page;

      final hotelSearchResults =
          hotelSearchRipository.getHotelSearchResults(requestData);

      hotelSearchResults.then((resource) async* {

        var status = resource.status;

        switch (status) {
          case DataRetrieveStatus.SUCCESS:
            yield HotelSearchData(resource.data);
            break;
          case DataRetrieveStatus.RESPONSE_ERROR:
          case DataRetrieveStatus.CONNECTION_ERROR:
          case DataRetrieveStatus.PROCESSING_ERROR:
            yield HotelSearchError(resource.displayMessage);
            break;
        }

      });
    }
  }
}

我已经通过在 hotelSearchResults.then((resource) async* {} 语句中放置一个调试点进行了测试,但它从未 triggers.Is 我的代码中出现错误?非常感谢任何帮助发现我的代码中的错误的人。

yield adds an object to the Iterable (sync*) or Stream (async*) associated with the immediately enclosing function.

使用 awaitgetHotelSearchResults()yield 新状态重写代码,仅在 mapEventToState() 函数范围内

Stream<DataretrieveState> mapEventToState(DataretrieveEvent event) async* {
  // this part of code is in lexical scope of mapEventToState()
  final resource = await hotelSearchRipository.getHotelSearchResults(requestData);

  var status = resource.status;

  switch (status) {
    case DataRetrieveStatus.SUCCESS:
      yield HotelSearchData(resource.data);
      break;
    case DataRetrieveStatus.RESPONSE_ERROR:
    case DataRetrieveStatus.CONNECTION_ERROR:
    case DataRetrieveStatus.PROCESSING_ERROR:
      yield HotelSearchError(resource.displayMessage);
      break;
  }
} // end of mapEvent

问题出在哪里?

futureFoo.then((resource) async* { yield SomeObject();});
  1. 由标记为 async* 生成器的匿名函数返回的新 Stream
  2. yield 项给这个 Stream
  3. 但是没有人听这个流

我坚持要你阅读有关 generators

的文档