이번에는 두 번째 비동기 바로바로
위 사진에서 볼 수 있듯이 Future는 단 한 번 받아내는 비동기 프로그래밍에 사용한다. 지속적으로 값을 반환 받을 때는 Stream을 사용한다. Stream은 한 번 리슨(Listen) 하면 Stream에 주입되는 모든 값들을 지속적으로 받아온다.
import 'dart:async';
void main() {
final controller = StreamController(); // StreamController 선언
final stream = controller.stream; // Stream 가져오기
// Stream에 listen() 함수를 실행하면 값이 주입될 때마다 콜백 함수를 실행
final streamListener1 = stream.listen((val) {
print(val);
});
// Stream에 값 주입
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
}
1
2
3
4
Stream을 사용하려면 Flutter에서 기본으로 제공하는 dart:async 패키지를 불러와야 합니다. 그다음 dart:async 패키지에서 제공하는 StreamController를 listen()해야 값을 지속적으로 반환 받을 수 있습니다.
import 'dart:async';
void main() {
final controller = StreamController();
// 여러 번 리슨할 수 있는 BroadCast Stream 객체 생성
final stream = controller.stream.asBroadcastStream();
// 첫 listen() 함수
final streamListener1 = stream.listen((val) {
print('$val 1');
});
// 둘 listen() 함수
final streamListener2 = stream.listen((val) {
print('$val 2');
});
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
}
1 1
1 2
2 1
2 2
3 1
3 2
Stream은 단 한 번만 listen()을 실행할 수 있다. 하지만 때때로 하나의 스트림을 생성하고 여러 번 listen() 함수를 실행해야 할 때가 있다. 이럴 경우 브로드캐스트 스트림을 사용하면 Stream을 여러번 listen()하도록 변환할 수 있다.
import 'dart:async';
// Stream을 반환하는 함수는 async*로 선언합니다.
Stream<String> calculate(int number) async* {
for (int i = 0; i < 5; i++) {
// StreamController의 add()처럼 yield키워드를 이용해서 값 반환
yeild 'i = $i';
await Future.delayed(Duration(second: 1));
}
}
void playSrream() {
// StreamController와 마찬가지로 listen() 함수로 콜백 함수 입력
calculate(1).listen((val) {
print(val);
});
}
void main() {
playStream();
}
StreamController를 직접 사용하지 않고도 직접 Stream을 반환하는 함수를 작성할 수 있다. Future를 반환하는 함수는 async로 선언하고 return 키워드로 반환하지만 Stream의 경우 async*로 선언 하고 yield 키워드로 값을 반환하면 된다.