К содержимому

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, которое позволяет обрабатывать ошибки/загрузку.