다트 Stream
Stream
데이터가 연속적으로 전달될 때 이를 수신하고 처리할 수 있도록 도와주는 비동기적 데이터 구조에요.
Future가 단일 값을 반환하는 비동기 연산이라면, Stream은 여러 개의 값을 순차적으로 전달받을 수 있습니다.
따라해보기
1️⃣ Stream 생성
Dart에서 스트림을 생성하는 방법은 여러 가지가 있습니다.
(1) StreamController를 사용하여 생성
import 'dart:async';
void main() {
final controller = StreamController<int>();
controller.stream.listen((data) {
print('Received: $data');
}, onDone: () {
print('Stream closed');
});
controller.add(1);
controller.add(2);
controller.add(3);
controller.close();
}
(2) async* 키워드를 사용하여 생성
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
yield i;
await Future.delayed(Duration(seconds: 1));
}
}
void main() async {
await for (var value in countStream(5)) {
print('Received: $value');
}
}
2️⃣ Stream 구독 (Listen)
final stream = Stream.periodic(Duration(seconds: 1), (count) => count);
final subscription = stream.listen((data) {
print('Received: $data');
});
3️⃣Stream 변환 (map, where, take 등 활용)
final stream = Stream.fromIterable([1, 2, 3, 4, 5]);
stream
.map((event) => event * 2)
.where((event) => event > 5)
.listen((data) {
print('Filtered: $data');
});
종류
단일 구독 스트림
- 기본 스트림이며 한 번만 구독할 수 있습니다.
- 파일 읽기, 네트워크 요청 등에서 사용됩니다.
브로드캐스트 스트림
- 여러 리스너가 동시에 구독할 수 있는 스트림입니다.
- UI 이벤트 처리, WebSocket과 같은 실시간 데이터 처리에 적합합니다.
final streamController = StreamController<int>.broadcast();
streamController.stream.listen((event) => print('Listener 1: $event'));
streamController.stream.listen((event) => print('Listener 2: $event'));
streamController.add(1);
streamController.add(2);