Stream 사용하기


import 'dart:async'; // Stream 사용하기 위해 필요

void main() {
  final controller = StreamController();
  final stream = controller.stream; // controller에서 stream 가져오기 (1번 리스닝 가능한 리소스 생성)
  
  // listen() : 하나의 함수를 파라미터로 받음
  // listen의 파라미터 함수(paramFun)에서도 첫 번째 파라미터에 값을 받음 
  // paramFun이 listen 하고 있다가 val이 들어오면 paramFun 실행 
  final streamListener1 = stream.listen((val){
    print('Listener 1 : $val');
  });
  
  controller.sink.add(1); // controller에 값 넣기 : listen()에 값 전달하는 것
  controller.sink.add(2); // 한 스트림에 여러 개의 값 전달 가능
  controller.sink.add(3);
  controller.sink.add(4);
  controller.sink.add(5);
}

// 실행결과
Listener 1 : 1
Listener 1 : 2
Listener 1 : 3
Listener 1 : 4
Listener 1 : 5

여러 리스너 선언


import 'dart:async'; // Stream 사용하기 위해 필요

void main() {
  final controller = StreamController();
  final stream = controller.stream.asBroadcastStream(); // 여러 번 리스닝 가능한 스트림 생성

  final streamListener1 = stream.listen((val){
    print('Listener 1 : $val');
  });
  
  final StreamListener2 = stream.listen((val){
    print('Listener 2 : $val');
  });
  
  
  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);
  controller.sink.add(4);
  controller.sink.add(5);
}

// 실행결과 : Listener1과 Listener2 번갈아가며 listening
Listener 1 : 1
Listener 2 : 1
Listener 1 : 2
Listener 2 : 2
Listener 1 : 3
Listener 2 : 3
Listener 1 : 4
Listener 2 : 4
Listener 1 : 5
Listener 2 : 5

Listener에 where() 적용

  final streamListener1 = stream.where((val) => val % 2 == 0).listen((val){
    print('Listener 1 : $val');
  });
  
  final StreamListener2 = stream.where((val) => val % 2 == 1).listen((val){
    print('Listener 2 : $val');
  });
  
// 실행결과 : Listener1은 짝수만, Listener2는 홀수만 listening
Listener 2 : 1
Listener 1 : 2
Listener 2 : 3
Listener 1 : 4
Listener 2 : 5

함수로 스트림 제공하기


import 'dart:async'; // Stream 사용하기 위해 필요
// Stream을 반환하는 함수 선언 (+ yield)
Stream<int> calculate(int number) async* {
  for (int i = 0; i < 5; i++) {
    yield i * number; 
    // yield가 실행될 때마다 이 값을 calculate를 listen하고 있는 listener에 값 제공 가능
  }
}
// 메인에서 사용
void main() {
  calculate(1).listen((val){
    print('calculate(1) : $val');
  });
}

// 실행결과
calculate(1) : 0
calculate(1) : 1
calculate(1) : 2
calculate(1) : 3
calculate(1) : 4

================================================================================
void main() {
  calculate(2).listen((val){
    print('calculate(1) : $val');
  });
}

// 실행결과
calculate(1) : 0
calculate(1) : 2
calculate(1) : 4
calculate(1) : 6
calculate(1) : 8

일반적인 Future 관련된 async 함수를 async* 함수에서 사용하기

import 'dart:async'; 

void main() {
  calculate(2).listen((val){
    print('calculate(2) : $val');
  });
}

Stream<int> calculate(int number) async* {
  for (int i = 0; i < 5; i++) {
    yield i * number; 
    
    await Future.delayed(Duration(seconds: 1)); // async* 에서 Future async 사용
    // 1초마다 listener에 yield 값 전달
  }
}