플러터의 비동기 시스템인 Future와 Stream의 차이를 알아보자.
비동기 작업 하나를 처리할 때 사용하는 객체이다. 파일 1개 읽어오기, 사용자 데이터 1개 가져오기 등...때문에 작업 하나를 완료하고 나서 값을 반환한다.
async 태그를 붙여서 해당 함수가 비동기라는 사실을 명시해야만 쓸 수 있다.Stream은 연속적인 데이터 흐름을 뜻한다.
언젠가 수업시간에...Stream은 데이터가 발생하면 그것을 감지하고 전달하는 개념이라기보다는, 강물이 계속 흘러가고 그 흐름을 따라 데이터가 둥둥 떠서 이동하는 것에 가깝다고 들은 적 있다. 이렇게 생각해보면 단순히 Future를 여러 번 실행하는 것과 명확한 차이점이 느껴질 것이다.
참고 문서 : https://api.flutter.dev/flutter/dart-async/Stream-class.html
플러터에서 Stream은 지속적으로 발생하는 여러 가지 비동기 이벤트를 다루는 객체이다. 예를 들어 채팅 시스템을 만든다면, 채팅을 종료할 때까지 계속해서 메시지를 주고받아야 하기 때문에 Stream을 사용하는 것이 적절하다.
Stream은 데이터가 발생할 때마다 반환하는데 이때 return이 아닌 yield(반환 후에도 함수 유지)를 쓴다. 공식 문서에 따르면 Stream에서 전달하는 것은 data event 또는 error event이며, 모든 이벤트를 전달하고 나면 listner에게 done 이벤트를 전달한다. 이 이벤트를 전달받으면 리스너는 스트림을 종료한다.
StreamListener
Stream 구독을 관리하는 위젯이다. Stream은 데이터를 지속적으로 반환하기 때문에 특정 오브젝트에 반환값을 담는 것이 아니고, 구독이라는 시스템을 통해서 정기적으로 데이터를 관찰할 필요가 있다.
Stream.listen으로 subscription을 시작하면StreamSubscription객체가 반환되고, 이 subscription이 위젯에게 이벤트를 전달하는 방식이다.
그러면 Stream은 특정 데이터에서 오류가 발생해도 그 데이터만 오류 처리를 하고 다음 데이터를 마저 받는 것인지 궁금해졌는데 이 역시 공식 문서에 적혀 있었다.
오류 데이터를 감지하면 데이터를 전달하던 루프가 오류를 throw하고 루프를 중단한다.
그런데 여기에 따로 오류를 catch하는 구문이 없기 때문에 루프를 벗어난 error data가 Stream의 구문 끝에 도달하고 반환된다.
그러면 Stream이 반환되는 타이밍에 오류가 발생한다.
*async를 붙여 선언하면 Single-subscription이 된다.StreamController.broadcast() 로 정의하여 사용할 수 있다. 여러 곳에서 데이터를 참조해야 할 때 Broadcast를 쓴다.