Ответ
В Flutter snapshot (снимок) — это объект, инкапсулирующий текущее состояние асинхронной операции. Он используется виджетами FutureBuilder и StreamBuilder для безопасного построения UI на основе данных, которые могут быть в процессе загрузки, успешно получены или содержать ошибку.
Структура AsyncSnapshot:
Объект AsyncSnapshot<T> содержит несколько критически важных свойств:
connectionState: Текущая фаза (ConnectionState.waiting,.active,.done).data: Успешно полученные данные типаT(илиnull).error: Объект ошибки, если операция завершилась с исключением.hasData/hasError: Булевы флаги для удобной проверки.
Практический пример с FutureBuilder для загрузки профиля:
FutureBuilder<UserProfile>(
future: _fetchUserProfile(), // Future<UserProfile>
builder: (context, AsyncSnapshot<UserProfile> snapshot) {
// 1. Проверяем состояние соединения и наличие ошибки
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Ошибка: ${snapshot.error}'));
}
// 2. Данные гарантированно есть, можно безопасно обращаться к snapshot.data
final user = snapshot.data!;
return Column(
children: [
Text('Имя: ${user.name}'),
Text('Email: ${user.email}'),
],
);
},
)
Ключевая идея: Snapshot отделяет логику асинхронного получения данных от синхронного процесса построения виджетов, предоставляя согласованный и типобезопасный интерфейс для работы с состоянием «загрузка-данные-ошибка».
Ответ 18+ 🔞
Давай разберем эту тему про snapshot во Flutter, а то некоторые её так боятся, будто это хуй с горы какой-то. На самом деле, всё проще, чем кажется.
Представь, что ты послал своего корега за пивом. Пока он не вернулся — это ConnectionState.waiting. Он вернулся с двумя холодными — это ConnectionState.done, а в руках у него data (это пиво). А если он вернулся с пустыми руками и синяком под глазом — это hasError, и в error будет записано «отжали на лестничной клетке».
Вот этот весь цирк с уходом, ожиданием и результатом — это и есть AsyncSnapshot. Он просто объект-контейнер, который говорит: «Э, бошка думай, данные ещё грузятся», «Всё, приехали, вот твои данные» или «Ёпта, всё накрылось медным тазом, вот ошибка».
Из чего эта мудя состоит:
У каждого снимка (AsyncSnapshot<T>) есть главные свойства, на которые надо смотреть:
connectionState: Фаза процесса. Ждём (waiting), в процессе (active) или всё (done).data: Собственно, данные, которые ты ждал. Пока их нет — тутnull.error: Если всё пошло по пизде, сюда положат объект ошибки.hasData/hasError: Просто удобные флаги, чтобы не писать километровые проверки.hasError— это как «чувак, тут ошибка», аhasData— «о, данные пришли, можно работать».
Пример из жизни, чтобы вообще всё стало ясно:
Допустим, ты грузишь профиль пользователя. Вот как это выглядит в коде с FutureBuilder:
FutureBuilder<UserProfile>(
future: _fetchUserProfile(), // Твой асинхронный запрос за профилем
builder: (context, AsyncSnapshot<UserProfile> snapshot) {
// 1. Первым делом — проверяем, не завис ли где-то запрос
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator()); // Показываем крутилку
}
// 2. Проверяем, не прилетела ли ошибка (корега всё-таки отпинали)
if (snapshot.hasError) {
return Center(child: Text('Ошибка: ${snapshot.error}'));
}
// 3. Если мы здесь — значит, не ждём и ошибок нет. Данные гарантированно есть!
// Восклицательный знак (!) — это мы говорим Dart'у: «Расслабься, я уверен, тут не null».
final user = snapshot.data!;
return Column(
children: [
Text('Имя: ${user.name}'),
Text('Email: ${user.email}'),
],
);
},
)
Суть всей этой ебли:
Главная фишка snapshot — это разделение ответственности. Асинхронная, долгая и ненадёжная операция по добыванию данных идёт своим путём. А твой UI-код, который должен быть быстрым и отзывчивым, работает синхронно. Snapshot — это просто связной между ними. Он приносит актуальную сводку с фронта: «грузим», «всё ок» или «пиздец». И ты на основе этой сводки спокойно решаешь, что показывать: крутилку, данные или сообщение об ошибке. Без всяких нервных срывов и try-catch на ровном месте.