ниже приведен фрагмент кода из учебника, который я пытаюсь изучить. признателен, если бы вы могли сказать мне, почему мы не используем защиту: asyncvalue.guard внутри build(), но позже используемую при вызове того же метода?
@riverpod
class WeatherFirst extends _$WeatherFirst {
@override
FutureOr<String> build() {
return _getTemp(Cities.seoul);
}
Future<String> _getTemp(Cities city) async {
await Future.delayed(const Duration(seconds: 1));
switch (city) {
case Cities.seoul:
return '${city.name} - 23';
case Cities.london:
throw 'Fail to fetch the temperature of ${city.name}';
case Cities.bangkok:
throw 'Fail to fetch the temperature of ${city.name}';
case Cities.tokyo:
return '${city.name} - 28';
}
}
Future<void> getTemperature(Cities city) async {
state = const AsyncLoading();
state = await AsyncValue.guard(() => _getTemp(city));
}
}
я пробовал вставлять различные сценарии ошибок, код работает нормально
Это код AsyncValue.guard
static Future<AsyncValue<T>> guard<T>(Future<T> Function() future) async {
try {
return AsyncValue.data(await future());
} catch (err, stack) {
return AsyncValue.error(err, stack);
}
}
все, что он делает, это оборачивает вашу функцию в выражение try catch
, чтобы сэкономить несколько строк кода. если вы уверены, что _getTemp(city)
не может выдать ошибку, вам вообще не нужно использовать защиту. если вы считаете, что _getTemp(Cities.seoul)
может выдать ошибку, вам следует вернуть AsyncValue.guard(() => _getTemp(Cities.seoul))
в методе сборки.
в приведенном примере город Сеул не выдает ошибку как Лондон и Бангкок, и это причина не использовать охрану
Редактировать
Я был неправ в своем ответе: не следует ставить защиту в методе сборки. это обрабатывается за вас, как указано в исходном коде:
/// If this method throws or returns a future that fails, the error
/// will be caught and an [AsyncError] will be emitted.
/// {@endtemplate}
@visibleForOverriding
FutureOr<State> build();