[flutter] - RxDart : Stream Classes Part2
Stream Classes
각 내용들을 이어서 하나씩 알아보자
- 순서
ReapetStream
- Example :
RepeatStream((int repeatCount) => Stream.value('repeat index: $repeatCount'), 3) .listen((i) => print(i)); // Prints 'repeat index: 0, repeat index: 1, repeat index: 2'
Repeat
은 말그대로 Stream
이 종료되었을 때 다시 Stream
을 생성하며 Listen
도 다시 반복한다.
repeatCount
를 지정하지 않을 경우 무한히 반복된다.
Stream.value('repeat index: $repeatCount'), 3)
뒤에 있는 숫자가 repeatCount
RetryStream
- Example :
RetryStream(() { Stream.fromIterable([1]); }) .listen((i) => print(i)); // Prints 1 RetryStream(() { Stream.fromIterable([1]) .concatWith([ErrorStream(Error())]); }, 1) .listen(print, onError: (e, s) => print(e)); // Prints 1, 1, RetryError
Rx.retry(() { Stream.value(1); }) .listen((i) => print(i); // Prints 1 Rx .retry(() { Stream.value(1).concatWith([Stream.error(Error())]); }, 1) .listen(print, onError: (e, s) => print(e); // Prints 1, 1, RetryError
Retry
는 Repeat
Rxdart
문서를 보면 똑같이 설명되있다. 하지만 다르게 동작한다.
Repeat
은 횟수만큼 반복동작하지만Retry
는 성공할 때까지 반복한다.
RxDart
공식 문서에는 설명이 햇갈리게 되있어서 issue를 등록해봤다.
RetryWhenStream
- Example :
bool errorHappened = false; RetryWhenStream( () => Stream .periodic(const Duration(seconds: 1), (i) => i) .map((i) { if (i == 3 && !errorHappened) { throw 'We can take this. Please restart.'; } else if (i == 4) { throw 'It\'s enough.'; } else { return i; } }), (e, s) { errorHappened = true; if (e == 'We can take this. Please restart.') { return Stream.value('Ok. Here you go!'); } else { return Stream.error(e); } }, ).listen( print, onError: (e, s) => print(e), ); // Prints 0, 1, 2, 0, 1, 2, 3, RetryError
Retry
와 이름은 비슷하지만 행동은 복잡하다.
먼저 Retry
와 비슷하게 정상적인 경우에는 똑같이 동작한다. 하지만 위의 코드와 같이 에러가 발생하게되면 아래쪽 retryWhenFactory
이 동작하게 된다. 그곳에서는 에러 내용을 보고 정상 동작을 시켜줄 수 있으며 그 곳에서도 error
가 발생하게되면 종료하게된다.
SequenceEqualStream
- Example :
SequenceEqualStream( Stream.fromIterable([1, 2, 3, 4, 5]), Stream.fromIterable([1, 2, 3, 4, 5]) ) .listen(print); // prints true
SequenceEqualStream( Stream.fromIterable([1, 2, 3, 4, 5]), Stream.fromIterable([1, 2, 3, 4, 5]), equals: check) .listen(print);
SequenceEqual
은 이름과 같이 내부 데이터의 순서
가 중요하다. 순서
가 동일할 경우 True
틀릴 경우 False
를 반환한다. 아래 코드처럼 equals
에 함수를 넣을 경우 함수의 내용대로 비교하여 True
, False
를 반환한다.
이것도 API문서에서 example코드가 잘못되있다…
SwitchLatestStream
- Example :
final switchLatestStream = SwitchLatestStream<String>( Stream.fromIterable(<Stream<String>>[ Rx.timer('A', Duration(seconds: 2)), Rx.timer('B', Duration(seconds: 1)), Stream.value('C'), ]), ); // Since the first two Streams do not emit data for 1-2 seconds, and the 3rd // Stream will be emitted before that time, only data from the 3rd Stream // will be emitted to the listener. switchLatestStream.listen(print); // prints 'C'
SwitchLatest
은 여러 Stream
중에서 가장 마지막에 들어온 Stream
을 Listen
하게 된다.
- Example :
final switchLatestStream = SwitchLatestStream<String>( Stream.fromIterable(<Stream<String>>[ Stream.fromIterable(['a', 'b', 'c']), Stream.fromIterable(['d', 'e', 'f']), Rx.timer('A', Duration(microseconds: 2)), Rx.timer('B', Duration(seconds: 1)), Stream.fromIterable(['g', 'h', 'i']), ]), ); switchLatestStream.listen(print); // prints a d g h i // 첫번쨰 스트림 a b c // 두번째 스트림 d e f // 세번째 스트림 g h i // 에서 가장 마지막 stream인 g h i 리슨
예시를 보면 마지막으로 데이터가 들어온 [g h i]
을 listen
하게 된다.
Duration
이 들어간stream
은 무시되는듯 하다.
TimerStream
- Example :
TimerStream('hi', Duration(minutes: 1)) .listen((i) => print(i)); // print 'hi' after 1 minute
Timer
는 Duration
후에 주어진 데이터를 출력한다.
CombineLatestStream
- Example :
CombineLatestStream.list<String>([ Stream.fromIterable(['a']), Stream.fromIterable(['b']), Stream.fromIterable(['C', 'D'])]) .listen(print); //prints ['a', 'b', 'C'], ['a', 'b', 'D']
CombineLatest
는 주어진 Stream
들을 결합하여 출력한다.
- Example :
CombineLatestStream( [ Stream.fromIterable(['a']), Stream.fromIterable(['b']), Stream.fromIterable(['C', 'D']) ], (values) => values.last ) .listen(print); //prints 'C', 'D'
이 예제에서는 들어오는 데이터들(
a b C
,a b D
)의 마지막C D
가 출력된다. - Example :
CombineLatestStream.combine2( Stream.fromIterable([1]), Stream.fromIterable([2, 3]), (a, b) => a + b, ) .listen(print); // prints 3, 4
이 예제에서는 들어온 데이터들을 조합하여 출력할 수 있다. (1
, 2 3
) => (1+2
, 1+3
)
ForkJoinStream
- Example :
ForkJoinStream.list<String>([ Stream.fromIterable(['d', 'a']), Stream.fromIterable(['b']), Stream.fromIterable(['C', 'D']) ]).listen(print); //prints ['a', 'b', 'D']
ForkJoin
은 Stream
그룹에서 가장 마지막 값만 모아서 출력해줍니다. 화면 로딩에서 많은 requests
후에 유용합니다.
- Example :
CombineLatestStream( [ Stream.fromIterable(['a']), Stream.fromIterable(['b']), Stream.fromIterable(['C', 'D']) ], (values) => values.last ) .listen(print); //prints 'D'
이 예제에서는 CombineLatest
와 다르게 마지막 값이 a b D
이기 때문에 마지막 값 D
가 출력됩니다.
- Example :
ForkJoinStream.combine2( Stream.fromIterable([1]), Stream.fromIterable([2, 3]), (a, b) => a + b, ) .listen(print); // prints 4
이 예제에서도 CombineLatest
와 비슷하게 출력 결과물에 함수를 사용하여 조작이 가능하지만 결과 값은 가장 마지막 데이터인 4
만 출력됩니다.
RangeStream
- Example :
RangeStream(1, 3).listen((i) => print(i)); // Prints 1, 2, 3 RangeStream(3, 1).listen((i) => print(i)); // Prints 3, 2, 1
Range
는 범위를 지정해주고 사이 데이터들을 순서대로 출력해줍니다.
숫자만 가능
ZipStream
- Example :
ZipStream( [ Stream.fromIterable(['A']), Stream.fromIterable(['B']), Stream.fromIterable(['C', 'D']), ], (values) => values.join(), ).listen(print); // prints 'ABC'
Zip
은 주어진 Stream
들을 index
에 맞춰서 zip function
을 실행한 데이터를 출력한다. 여기서 zip function
은
(values) => values.join()
- Example :
ZipStream.zip3( Stream.fromIterable(['A', 'Z']), Stream.fromIterable(['B', 'Q', 'F']), Stream.fromIterable(['C', 'D', 'G']), (a, b, c) => a + b + c, ).listen(print); // prints 'ABC' , 'ZQD'
Zip
은 값에 대한 특별한 zip함수 실행을 위해 Zip2
~Zip9
까지 지원하며 뒤에 숫자는 Stream
갯수이다.
Classes 끝
이로써 Classes
를 모두 알아봤고 다음은 Extension Methods
를 알아보자