Flutter에서 데이터가 비동기적으로 처리되는 경우가 많습니다. 이러한 비동기 데이터 흐름을 관리하기 위해 Stream이라는 도구를 사용합니다. 이번 글에서는 Stream이 무엇인지, 왜 사용하는지, 그리고 실생활에서 어떻게 활용되는지를 저 같은 초보자도 이해할 수 있도록 쉽게 설명하겠습니다.
Stream이란?
Stream은 Dart에서 비동기 데이터 이벤트의 연속적인 흐름을 처리하기 위한 클래스입니다.
쉽게 말하면, Stream은 "데이터의 강"이라고 생각하면 됩니다. 이 강에서는 데이터가 하나씩(혹은 여러 개씩) 흘러오고, 이를 필요할 때마다 받아서 처리할 수 있습니다.
Stream의 작동 방식
Stream은 두 가지 주요 구성 요소로 이루어져 있습니다:
- Stream: 데이터를 제공하는 쪽입니다. "데이터를 흘려보내는 강"이라고 생각할 수 있습니다.
- Listener(구독자): 데이터를 소비하는 쪽입니다. "강에서 물을 퍼올리는 사람"에 해당합니다.
Stream을 사용하려면 먼저 데이터를 구독(subscribe)해야 합니다. 구독한 후에는 Stream에서 데이터를 받을 수 있습니다.
Stream의 종류
Stream에는 두 가지 주요 종류가 있습니다:
- Single-Subscription Stream
- 한 번에 하나의 리스너만 데이터를 구독할 수 있습니다.
- 주로 네트워크 요청, 파일 읽기 등 단일 이벤트 스트림에 사용됩니다.
Stream<int> numberStream() async* { for (int i = 1; i <= 5; i++) { await Future.delayed(Duration(seconds: 1)); yield i; } } void main() { numberStream().listen((number) { print('Received number: $number'); }); }
- Broadcast Stream
- 여러 리스너가 동시에 데이터를 구독할 수 있습니다.
- 주로 이벤트 버스나 실시간 데이터 스트림에 사용됩니다.
StreamController<String> controller = StreamController.broadcast(); void main() { controller.stream.listen((data) { print('Listener 1 received: $data'); }); controller.stream.listen((data) { print('Listener 2 received: $data'); }); controller.add('Hello, Stream!'); }
Stream을 사용하는 이유
- 비동기 데이터 처리
- 네트워크 요청, 파일 읽기, 사용자 입력 등 비동기적으로 발생하는 데이터를 효율적으로 처리할 수 있습니다.
- 실시간 데이터 스트림 관리
- 채팅 앱, 주식 가격 업데이트, 실시간 알림과 같은 앱에서 매우 유용합니다.
- 코드의 가독성 향상
- 데이터를 순차적으로 처리하거나 이벤트 기반 코드를 작성할 때 Stream을 사용하면 코드가 더 깔끔해집니다.
Stream을 활용한 예제
1. 네트워크 요청 처리
Stream을 사용하면 비동기 데이터 요청과 응답을 관리할 수 있습니다.
Stream<String> fetchServerData() async* {
await Future.delayed(Duration(seconds: 2));
yield 'Data from server';
}
void main() {
fetchServerData().listen((data) {
print(data);
});
}
2. 실시간 타이머
Stream을 활용해 타이머를 구현할 수도 있습니다.
Stream<int> timerStream(int seconds) async* {
for (int i = 1; i <= seconds; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
void main() {
timerStream(5).listen((tick) {
print('Tick: $tick');
});
}
3. 사용자 입력 처리
사용자가 입력하는 데이터를 실시간으로 처리하는 예제입니다.
import 'dart:async';
void main() {
final controller = StreamController<String>();
controller.stream.listen((input) {
print('You entered: $input');
});
controller.add('Hello, World!');
controller.add('Stream is awesome!');
}
Stream 사용 시 주의할 점
- Stream 구독 해제
- 구독한 Stream은 사용 후 반드시 해제해야 메모리 누수를 방지할 수 있습니다.
- StreamSubscription.cancel()을 사용하세요.
StreamSubscription<int> subscription; void main() { subscription = timerStream(5).listen((tick) { print('Tick: $tick'); }); Future.delayed(Duration(seconds: 3), () { subscription.cancel(); print('Stream cancelled'); }); }
- 에러 처리
- Stream에서 에러가 발생할 수 있으니 반드시 처리해 주세요.
void main() { timerStream(5).listen( (tick) { print('Tick: $tick'); }, onError: (error) { print('Error: $error'); }, onDone: () { print('Stream completed'); }, ); }
끝으로..
Stream은 Flutter에서 비동기 데이터와 실시간 이벤트를 효율적으로 처리하기 위한 도구입니다. 이번 글에서 소개한 기본 개념과 예제를 잘 활용하면, 앞으로 만드는 앱을 더 잘 만들 수 있을 것 같습니다!!
'TIL' 카테고리의 다른 글
Flutter의 const 키워드 (0) | 2025.01.15 |
---|---|
Flutter의 Key는 무엇인가요? (0) | 2025.01.15 |
Dart의 Garbage Collector란? (0) | 2025.01.13 |
클래스 내에서 static 키워드 (0) | 2025.01.10 |
Flutter의 빌드 모드에는 무엇이 있는지 알아보자 (0) | 2025.01.10 |