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.
使用 await
为 getHotelSearchResults()
和 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();});
- 由标记为
async*
生成器的匿名函数返回的新 Stream
- 你
yield
项给这个 Stream
- 但是没有人听这个流
我坚持要你阅读有关 generators
的文档
我是 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 theIterable
(sync*) orStream
(async*) associated with the immediately enclosing function.
使用 await
为 getHotelSearchResults()
和 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();});
- 由标记为
async*
生成器的匿名函数返回的新Stream
- 你
yield
项给这个Stream
- 但是没有人听这个流
我坚持要你阅读有关 generators
的文档