Blog

Streams во Flutter

Dart Streams

Streams – это потоки данных, испускаемых последовательно в количестве от 0 до n. Если проводить аналогии с RxJava, то это Stream работает как Observable. Это чистая реактивщина, которая присутствует в Dart из коробки.

Для того, чтобы получать данные из потока Stream, нужно подписаться на него.

final
 _stream = SomeGenerator().stream;
 final subscription = _stream.listen(
   (data) => print(‘$data’),
 );

Важный момент: По умолчанию на Stream может подписаться только один слушатель. Чтобы один Stream могли слушать несколько подписчиков, нужно вызвать на stream-е метод  asBroadсastStream

Также  можно слушать на ошибки, а также есть очень удобный флаг cancelOnError, который позволяет приложению не падать в случае ошибки в потоке. Что очень удобно, и не надо писать onErrorReturn как в RxJava.

final subscription = _stream.listen(
data) => print(‘$data’),
),
	onError:(err) {
		print(‘err’)
	},
	cancelOnError: false,
	onDone:() {
		print(‘Done)
	}
);

также, как и в Rx, у Stream-ов есть оператор map, который позволяет фильтровать испускаемые элементы:

final subscription = _ SomeGenerator().stream
	.where((data) => data.isValid() == true)
	.map((data) => ‘Valid $data’)
	.listen(
		(data) => print(‘$data’),

	);

StreamController

Для того, чтобы создать Stream вручную, нужно использовать класс StreamController. Это обертка над потоком Stream, которая позволяет отправлять данные в поток. Посмотрим исходник класса. В нем все достаточно просто. Stream c дженерик-типом и колбеки onListen, onPause, onResume, onCancel:

abstract class StreamController<T> implements StreamSink<T> {
  

/** The stream that this controller is controlling. */
  Stream<T> get stream;
  
. . .

/**
 
* The callback which is called when the stream is listened to.
 
*
 
* May be set to `null`, in which case no callback will happen.
 
*/

ControllerCallback get onListen;

void set onListen(void onListenHandler());



/**
 
* The callback which is called when the stream is paused.
 
*
 
* May be set to `null`, in which case no callback will happen.
 
*
 
* Pause related callbacks are not supported on broadcast stream controllers.
 
*/

ControllerCallback get onPause;

void set onPause(void onPauseHandler());



/**
 
* The callback which is called when the stream is resumed.
 
*
 
* May be set to `null`, in which case no callback will happen.
 
*
 
* Pause related callbacks are not supported on broadcast stream controllers.
 
*/

ControllerCallback get onResume;

void set onResume(void onResumeHandler());

Для того, чтобы отослать событие/данные в поток Stream, нужно на StreamController-е вызвать метод sink.add(<данные>). Как это работает на практике мы увидим дальше в примере со счетчиком, а сейчас отметим важный момент как использовать Stream в UI.

Чтобы UI, то есть виджет мог обновляются в соответсвии с изменениями, поступающими от потока Stream, этот виджет нужно обернуть в специальный виджет StreamBuilder. Этот виджет имеет параметр stream, в котором мы указываем поток с данными, а также функцию билдера, в котором, используя получаемые от потока данные, можно отрисовывать виджет.

StreamBuilder(
  stream: _myStream,
  initialData: <объект>,
  
	builder: (BuildContext context, AsyncSnapshot<Тип данных> snapshot) {
    
	eturn Text('${snapshot.объект}');
  
	},

),

Эта статья — из книги Быстрый старт Flutter-разработчика

Please follow and like us:
error

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *