Dart의 Stream은 비동기적으로 발생하는 데이터의 시퀀스를 처리하기 위한 강력한 도구입니다.
Stream을 사용하면 데이터 스트림을 구독하여 데이터가 도착할 때마다 처리할 수 있습니다.
이 글에서는 Dart에서 Stream의 기본 개념과 사용법, 관리 방법을 설명하겠습니다.
1. Stream이란?
Stream은 비동기적으로 발생하는 데이터의 연속적인 시퀀스를 처리하는 방법을 제공합니다. 예를 들어, 웹 소켓, 파일 I/O, 사용자 입력 등에서 발생하는 데이터를 처리할 때 유용합니다. Stream은 다음과 같은 주요 특징을 갖습니다.
- 연속적인 데이터 흐름: Stream은 여러 개의 데이터 이벤트를 순차적으로 처리합니다.
- 비동기 처리: 데이터는 비동기적으로 도착하며, 이를 처리하기 위한 비동기 메커니즘을 제공합니다.
- 데이터 구독: Stream은 구독자가 데이터를 받아볼 수 있도록 합니다.
2. Stream 생성
Stream을 생성하는 방법에는 여러 가지가 있습니다. 가장 기본적인 방법은 StreamController를 사용하는 것입니다.
2.1 StreamController 사용
StreamController는 Stream을 생성하고 데이터를 추가할 수 있는 객체입니다. 아래는 StreamController를 사용하여 Stream을 생성하고 데이터를 스트리밍하는 예제입니다.
import 'dart:async';
void main() {
final controller = StreamController<int>();
// Stream 구독
controller.stream.listen((data) {
print('Received: $data');
});
// 데이터 추가
controller.add(1);
controller.add(2);
controller.add(3);
// Stream 종료
controller.close();
}
이 코드에서는 StreamController<int>를 생성하고, stream.listen 메서드를 통해 데이터가 도착할 때마다 출력합니다.
add 메서드를 사용하여 데이터를 추가하고, 마지막에 close 메서드를 호출하여 Stream을 종료합니다.
2.2 Stream 생성자 사용
다음은 Stream의 생성자를 사용하여 비동기적으로 데이터를 생성하는 예제입니다.
import 'dart:async';
void main() {
final stream = Stream<int>.periodic(Duration(seconds: 1), (count) => count);
// Stream 구독
stream.listen((data) {
print('Received: $data');
});
}
위 코드에서는 Stream.periodic을 사용하여 매초마다 숫자를 생성하는 Stream을 만듭니다.
이 Stream은 계속해서 숫자를 발생시키며, 구독자는 이러한 숫자를 수신합니다.
3. Stream의 데이터 처리
Stream의 데이터는 listen 메서드를 통해 처리할 수 있습니다. listen 메서드는 데이터 이벤트가 발생할 때마다 호출됩니다.
추가로 onError와 onDone 콜백을 통해 오류 처리와 완료 처리를 할 수 있습니다.
import 'dart:async';
void main() {
final stream = Stream<int>.periodic(Duration(seconds: 1), (count) {
if (count == 3) throw 'Error occurred';
return count;
});
stream.listen(
(data) => print('Received: $data'),
onError: (error) => print('Error: $error'),
onDone: () => print('Stream closed'),
cancelOnError: true
);
}
- onError 콜백: 스트림에서 오류가 발생할 때 호출됩니다.
- onDone 콜백: 스트림이 완료되었을 때 호출됩니다.
- cancelOnError 옵션: 오류 발생 시 스트림 구독을 자동으로 취소할지 여부를 설정합니다.
4. Stream의 다양한 유형
Dart에서는 다양한 유형의 Stream을 사용할 수 있습니다.
4.1 단일 구독 스트림 (Single Subscription Stream)
단일 구독 스트림은 한 번에 하나의 구독자만 가질 수 있습니다. StreamController를 사용하여 단일 구독 스트림을 생성할 수 있습니다.
4.2 브로드캐스트 스트림 (Broadcast Stream)
브로드캐스트 스트림은 여러 구독자가 동시에 구독할 수 있는 스트림입니다. StreamController.broadcast를 사용하여 브로드캐스트 스트림을 생성할 수 있습니다.
import 'dart:async';
void main() {
final controller = StreamController<int>.broadcast();
controller.stream.listen((data) {
print('Subscriber 1: $data');
});
controller.stream.listen((data) {
print('Subscriber 2: $data');
});
controller.add(1);
controller.add(2);
controller.add(3);
controller.close();
}
이 예제에서는 두 개의 구독자가 동일한 브로드캐스트 스트림을 구독하고 데이터를 받습니다.
5. 스트림 변환
Stream의 데이터를 변환하거나 필터링하는 다양한 방법이 있습니다. 주요 변환 메서드는 다음과 같습니다:
- map: 스트림의 각 데이터를 변환합니다.
- where: 특정 조건을 만족하는 데이터만 필터링합니다.
- asyncExpand: 스트림의 각 데이터에 대해 또 다른 스트림을 생성합니다.
- distinct: 중복된 데이터를 제거합니다.
import 'dart:async';
void main() {
final stream = Stream<int>.periodic(Duration(seconds: 1), (count) => count)
.take(5)
.map((data) => data * 2)
.where((data) => data.isEven);
stream.listen((data) {
print('Received: $data');
});
}
위 코드는 Stream의 데이터를 두 배로 늘리고, 짝수만 필터링하여 출력합니다.
6. 스트림과 async/await
Stream을 사용할 때 async/await을 활용하여 비동기적으로 스트림을 처리할 수 있습니다.
import 'dart:async';
void main() async {
final stream = Stream<int>.periodic(Duration(seconds: 1), (count) => count)
.take(5);
await for (var data in stream) {
print('Received: $data');
}
}
이 코드에서는 await for을 사용하여 스트림의 데이터를 순차적으로 처리합니다.
Dart에서 Stream은 비동기적으로 발생하는 데이터의 시퀀스를 처리하는 강력한 도구입니다.
StreamController를 사용하여 스트림을 생성하고, listen 메서드를 통해 데이터를 처리할 수 있습니다.
다양한 Stream 유형과 변환 메서드를 활용하여 복잡한 비동기 작업을 효율적으로 처리할 수 있습니다.
async/await과 결합하여 비동기 스트림을 간결하게 처리하는 방법도 매우 유용합니다.
구독!! 공감과 댓글은 저에게 큰 힘이 됩니다.
Starting Google Play App Distribution! "Tester Share" for Recruiting 20 Testers for a Closed Test.
'Dart > Dart Programming language' 카테고리의 다른 글
[중급] Dart 클래스 심화/Mixins와 with 키워드 활용법 (0) | 2024.09.06 |
---|---|
[중급] Dart 클래스 심화/ 추상 클래스와 인터페이스 이해하기 (0) | 2024.09.06 |
[중급] Dart 비동기 프로그래밍/ Future와 async/await 기본 개념 이해하기 (1) | 2024.09.06 |
[중급] Dart 예외 처리 및 디버깅/ 디버깅 기법 및 로그 출력 방법 (0) | 2024.09.06 |
[중급] Dart예외 처리 및 디버깅/ 커스텀 예외 생성 및 활용법 (0) | 2024.09.06 |