중급
Stream
시간에 따라 여러 값이 흘러오는 데이터를 Stream으로 다룹니다.
개념 먼저 보기
Stream의 기본 개념부터 잡기
Stream 문서는 먼저 용어의 뜻을 잡고, 그 다음 Flutter 코드에서 어디에 쓰이는지 연결해서 읽는 것이 좋습니다.
아래 항목들은 이 문서에서 다루는 내용을 작은 단위로 나눈 것입니다. 각 항목을 읽은 뒤 예제를 보면 코드가 훨씬 덜 추상적으로 느껴집니다.
종류별로 하나씩
Stream에서 나눠 볼 핵심 요소
Stream의 성격
Future가 한 번의 완료라면 Stream은 여러 번의 이벤트입니다.
언제 쓰나: 채팅 메시지, 실시간 DB, WebSocket, 센서 값처럼 계속 변하는 데이터에 어울립니다.
Flutter에서: 구독을 만들었다면 필요 없어질 때 해제해야 합니다.
// Stream 예제입니다.
// 먼저 코드의 큰 흐름을 보고, 주석을 따라 각 줄의 역할을 확인하세요.
Stream<int> ticker() async* {
for (var i = 0; i < 3; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
}
Flutter 연결
StreamBuilder는 stream의 상태를 UI로 바꿔 주는 기본 위젯입니다.
언제 쓰나: snapshot.connectionState로 대기, 활성, 완료 상태를 구분합니다.
Flutter에서: 오류와 빈 데이터 상태도 화면에 표현해야 합니다.
// Stream 예제입니다.
// 먼저 코드의 큰 흐름을 보고, 주석을 따라 각 줄의 역할을 확인하세요.
Stream<int> ticker() async* {
for (var i = 0; i < 3; i++) {
await Future.delayed(const Duration(seconds: 1));
yield i;
}
}
부연 설명
Stream의 성격
- Future가 한 번의 완료라면 Stream은 여러 번의 이벤트입니다.
- 채팅 메시지, 실시간 DB, WebSocket, 센서 값처럼 계속 변하는 데이터에 어울립니다.
- 구독을 만들었다면 필요 없어질 때 해제해야 합니다.
부연 설명
Flutter 연결
- StreamBuilder는 stream의 상태를 UI로 바꿔 주는 기본 위젯입니다.
- snapshot.connectionState로 대기, 활성, 완료 상태를 구분합니다.
- 오류와 빈 데이터 상태도 화면에 표현해야 합니다.
깊게 이해하기
Stream은 여러 값이 시간 순서대로 도착하는 통로입니다. 채팅, 실시간 문서, 위치 추적처럼 값이 계속 갱신되는 기능에서 Future보다 자연스럽습니다.
Stream을 쓰면 구독 생명주기가 생깁니다. 위젯이 사라진 뒤에도 구독이 살아 있으면 메모리 누수나 중복 이벤트가 발생할 수 있습니다.
상세 예제
검색어 입력을 스트림으로 받아 디바운스 후 결과를 갱신하는 개념 예제입니다.
final controller = StreamController<String>();
late final StreamSubscription<String> subscription;
void initSearch() {
subscription = controller.stream
.where((query) => query.trim().length >= 2)
.listen((query) {
print('검색 실행: $query');
});
}
void disposeSearch() {
subscription.cancel();
controller.close();
}
실무에서 주의할 점
- 직접 listen했다면 dispose에서 cancel하세요.
- StreamBuilder에서는 대기, 오류, 빈 데이터 상태를 모두 처리하세요.
- 단발성 API 호출에는 Stream보다 Future가 더 단순합니다.
실습 체크리스트
Stream과 Future 차이 설명StreamBuilder 사용구독 해제 고려