FutureProvider
FutureProvider
является аналогом Provider, но для асинхронного кода.
FutureProvider
обычно используется для:
- выполнения и кэширования асинхронных операций (например сетевые запросы)
- красивая обработка ошибок/загрузок асинхронных операций
- комбинирование нескольких асинхронных значений в одном
FutureProvider
с ref.watch еще более полезен.
Такая комбинации позволяет автоматически получать новые данные
при изменении переменных. Тем самым мы гарантируем наличие актуальных данных.
FutureProvider
не предоставляет способа изменения вычислений после взаимодействия
пользователя. Он был создан для решения простых задач. Для более сложных ситуаций
следует использовать StateNotifierProvider.
Пример использования: чтение файла конфигурации
FutureProvider
может быть хорошим способом хранения объекта Configuration
,
созданного после прочтения JSON файла.
Создание конфигурации может быть реализовано с использованием async/await, но теперь внутри провайдера. Используя asset, это можно сделать так:
final configProvider = FutureProvider<Configuration>((ref) async {
final content = json.decode(
await rootBundle.loadString('assets/configurations.json'),
) as Map<String, Object?>;
return Configuration.fromJson(content);
});
Далее UI может наблюдать за конфигурацией:
Widget build(BuildContext context, WidgetRef ref) {
AsyncValue<Configuration> config = ref.watch(configProvider);
return config.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (config) {
return Text(config.host);
},
);
}
Таким образом, UI автоматически перестроится, когда завершится Future. В то же время, если конфигурация понадобится нескольким виджетам, файл конфигурации будет прочтен единожды.
Как вы можете видеть, прослушивание FutureProvider
внутри виджета
возвращает AsyncValue, которое позволяет обрабатывать ошибки/загрузку.