В чем разница между StreamBuilder и FutureBuilder в Flutter?

Ответ

StreamBuilder и FutureBuilder — это виджеты для работы с асинхронными данными, но они предназначены для разных типов источников.

FutureBuilder используется для обработки единичного асинхронного события (Future<T>). Он строит UI один раз, когда Future завершается (успешно или с ошибкой).

FutureBuilder<String>(
  future: _fetchUserProfile(), // Future, который выполнится один раз
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator();
    }
    if (snapshot.hasError) {
      return Text('Ошибка: ${snapshot.error}');
    }
    return Text('Данные: ${snapshot.data}');
  },
)

StreamBuilder предназначен для обработки потока данных (Stream<T>), который может выдавать множество значений с течением времени. Он перестраивает UI при каждом новом событии в потоке.

StreamBuilder<int>(
  stream: _messageCountController.stream, // Stream, который может эмитить много значений
  builder: (context, snapshot) {
    final count = snapshot.data ?? 0;
    return Badge(label: Text('$count')); // Badge обновляется при каждом новом значении
  },
)

Ключевое отличие: Future — это отложенное вычисление с одним результатом, а Stream — это последовательность асинхронных событий. FutureBuilder идеален для загрузки данных по API, а StreamBuilder — для обновлений в реальном времени, например, чатов или показателей с WebSocket.

Ответ 18+ 🔞

А, ну это же классика, ебать мои старые костыли! Сидишь такой, пишешь на Flutter, и тут бац — нужно данные подгрузить. И сразу встаёт вопрос, какого хуя выбрать: StreamBuilder или FutureBuilder? Это как выбрать между чаем, который заварил один раз, и кофемашиной, которая тебе льёт эспрессо каждые пять минут. Разница, блядь, принципиальная.

Смотри, FutureBuilder — это как раз про тот самый один раз. Заказал пиццу (Future), ждёшь доставку. Привезли — молодца, кушаешь. Не привезли или с ананасами — охуеваешь, но история закончена. Виджет один раз отрисуется на основе результата этого твоего Future. Идеально для загрузки профиля пользователя, списка товаров, всякой такой статики, которая не должна меняться каждую секунду.

FutureBuilder<String>(
  future: _fetchUserProfile(), // Разок дернул API и ждёшь
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return CircularProgressIndicator(); // Крутилка, пока курьер едет
    }
    if (snapshot.hasError) {
      return Text('Ошибка: ${snapshot.error}'); // Привезли хуйню вместо пиццы
    }
    return Text('Данные: ${snapshot.data}'); // Ура, жри!
  },
)

А теперь StreamBuilder — это уже ёперный театр. Это не пицца, а подписка на паблик ВКонтакте, откуда тебе постоянно сыпятся уведомления: лайк, коммент, репост, ещё лайк. Поток (Stream) данных, который может плодить события до овердохуища. Виджет будет перерисовываться каждый раз, когда в потоке появляется новое значение. Представь чат — сообщения же приходят постоянно, вот для этого он и создан.

StreamBuilder<int>(
  stream: _messageCountController.stream, // Канал, по которому числа прут как сумасшедшие
  builder: (context, snapshot) {
    final count = snapshot.data ?? 0; // Берём последнее значение или ноль
    return Badge(label: Text('$count')); // Бейджик обновляется сам, как только count изменится
  },
)

Так в чём, блядь, соль? Всё просто, как три копейки. Future — это обещание одного результата (успех или пиздец). Stream — это обещание последовательности результатов, их может быть хоть тысяча. Поэтому FutureBuilder — для разовой операции, типа «загрузи и покажи». А StreamBuilder — для всего, что живёт и дышит в реальном времени: онлайн-часы, курс биткоина, показания датчиков, сообщения в мессенджере. Если попробуешь чат на FutureBuilder сделать, то это будет пиздопроебибна — тебе придётся каждую секунду пинать Future заново. А так подписался на поток и сидишь, как падишах, данные сами приплывают.

Короче, запомни: один раз — FutureBuilder. Много раз — StreamBuilder. И волнение ебать сразу пропадёт.