RxSwift - 알아보기<Filtering(Taking)>

짠승이·2022년 2월 18일
0

Taking Operator

Skip -> 전 무시
Take -> 후 무시

take(count:)

take 는 skip 의 반대 개념으로

skip 은 인자로 보내는 index 만큼의 시퀀스를 무시합니다.

take 는 반대로 인자로 보내는 count 만큼의 시퀀스만 방출합니다.

  • Skip 은 지정된 값을 index 로 인식 그 index 후 부터 Emit
  • Take 는 지정된 값을 count 로 인식 그 count 까지 Emit

코드로 좀더 알기 쉽게 설명하면

        Observable<Int>
            .from([1,2,3,4,5,6])
            .take(2)
            .subscribe(onNext: {
                print($0)
            }).disposed(by: disposeBag)
   /*
   print
   1
   2
   */

take(untill:)

take(untill:) 은 skip(untill:) 의 반대 개념입니다.
skip(untill:) 의 개념은

  • 구독 하는 시퀀스와 Trigger 역할을 담당하는 두개의 시퀀스가 있습니다.
  • 구독 중인 시퀀스는 Trigger 시퀀스를 감시하며 Trigger 시퀀스가 요소를 방출하기 전까지
  • 구독 시퀀스는 어떠한 방출도 진행하지 않습니다. 그리고 Trigger 시퀀스 방출이 시작되면
  • 구독 시퀀스는 Trigger 시퀀스의 방출 이후에 요소들만 방출합니다.

take는 Trigger 시퀀스의 방출이 시작되기 전까지의 요소들만 방출합니다.

        let sub = PublishSubject<Int>() //Subscribe 시퀀스
        let trg = PublishSubject<Int>() //Trigger 시퀀스
        sub
            .take(until: trg)   // Trigger 시퀀스 감시 하기
            .subscribe(onNext: { // 구독
                print($0)
            }).disposed(by: disposeBag)
        sub.onNext(1)   // Subscribe 시퀀스 방출시작. 방출
        sub.onNext(3)   // 방출
        trg.onNext(4)   // Trigger 시퀀스 방출시작.
        sub.onNext(5)   // 무시
        sub.onNext(6)   // 무시
/*
print
1
3
*/
 

take(while:)

take 와 skip 은 서로 와 정반대의 성질을 띄고 있습니다.

while 또한 skip(while:) 의 경우

  • 조건에 맞는 요소들을 skip
  • skip 진행중 조건에 맞지 않는 요소가 나올시 그 뒤로부턴 전체 방출

크게 보면 이렇게 볼수 있습니다.

take(while:)의 경우는

  • 조건에 맞지 않는 요소가 나오기 전까지 조건에 맞는 요소들을 방출
  • 조건에 맞지 않는 요소가 나오면 그뒤로부터 전체 무시
        Observable<String>
            .from(["1","1","1","2","2","3","1"])
            .take(while: { $0 == "1"})
            .subscribe(onNext : {
                print($0)
            }).disposed(by: disposeBag)
/*
print
1
1
1
*/

이러한 output을 볼수 있습니다.

takeLast(count:)

takeLast 는 시퀀스의 뒤에서 부터 지정하는 count 만큼의 요소를 방출 시킵니다.

        Observable<String>
            .from(["1","1","1","2","2","3","1"])
            .takeLast(3)
            .subscribe(onNext : {
                print($0)
            }).disposed(by: disposeBag)
/*
print
2
3
1
*/

distinctUntilChanged()

중복값 무시

distinctUntilChanged 는 시퀀스 에는 중복값을 Filtering 해줍니다.

        Observable<String>
            .from(["1","1","1","2","2","3","1"])
            .distinctUntilChanged()
            .subscribe(onNext : {
                print($0)
            }).disposed(by: disposeBag)
            /*
            print
            1
            2
            3
            1
            */

여기서 자세히 볼필요가 있는 부분은 연속 이라는 점 같습니다.
중복되는 Event 가 연속적으로 발생할시 중복 값을 무시하지만
중복되지 않는 Event 발생후 다시 중복되는 Event가 방출되면 무시 하지 못합니다.

연속적으로 들어오는 중복값만 무시

Debounce

특정 시간 동안 Event 를 방출하지 않고 시간이 경과되어야 Event 방출

debounce 는 dueTime 와 scheduler 를 지정합니다.

지정한 scheduler 안에서 지정된 dueTime 안에서 벌어지는 Event는 방출하지 않고

지정된 시간 외에 발생하는 가장 최근 Event 만 Emit 합니다.

또한 Event 가 Emit 되면 Timer 는 초기화 됩니다.

여러번 Emit 되는 Event 들에 대응하기 좋은 Operator 라고 생각 됩니다.

어떠한 Event 방출에도 제한한 시간 에서의 최근 Event 만을 방출하기 때문에

사용자 의 연속적인 입력에 대비하기 좋고 자동완성 / 연관검색어 완성 부분에서 사용하기 유용할것 같습니다.

       Observable<Int>.interval(.seconds(2), scheduler: MainScheduler.instance)
            .take(10)
            .debounce(.seconds(1), scheduler: MainScheduler.instance)
            .debug("호호호히히히")
            .subscribe(onNext: {
                print($0)
            }).disposed(by: disposeBag)
           /*
           print
2022-02-18 17:41:36.881: 호호호히히히 -> subscribed
2022-02-18 17:41:39.885: 호호호히히히 -> Event next(0)
0
2022-02-18 17:41:41.884: 호호호히히히 -> Event next(1)
1
2022-02-18 17:41:43.884: 호호호히히히 -> Event next(2)
2
2022-02-18 17:41:45.884: 호호호히히히 -> Event next(3)
3
2022-02-18 17:41:47.883: 호호호히히히 -> Event next(4)
4
2022-02-18 17:41:49.884: 호호호히히히 -> Event next(5)
5
2022-02-18 17:41:51.883: 호호호히히히 -> Event next(6)
6
2022-02-18 17:41:53.884: 호호호히히히 -> Event next(7)
7
2022-02-18 17:41:55.884: 호호호히히히 -> Event next(8)
8
2022-02-18 17:41:56.883: 호호호히히히 -> Event next(9)
9
2022-02-18 17:41:56.884: 호호호히히히 -> Event completed
2022-02-18 17:41:56.884: 호호호히히히 -> isDisposed
*/

Throttle

Throttle 은 트위터에서 스크롤 버벅거림 관련 이슈를 해결하기 위해 제안한 방법론 이라고 합니다.

Throttle 은 Event 가 Emit 되면 dueTime 에 지정된 시간 에서 2개 이상의 Event 가 Emit 되지 않습니다.

  • dueTime : 해당 Operator 의 지속 시간을 지정합니다.
  • scheduler : 해당 Operator의 연산이 진행될 Thread 를 설정
  • latest : 지속 시간이 끝나기 전 마지막 Event를 Emit 할것인지 여부를 지정합니다.

    dueTime ( = x )

    lastest 의 default 는 true 입니다.


    " true : dueTime 안에서 방출되는 Event 들중 첫번째 와 마지막 Event 만 방출합니다.
    " false : 첫 번째 Event 만 방출합니다.

// tap , throttle 
buttonName.rx.tap
                .asObservable()
                .throttle(.milliseconds(500), scheduler: MainScheduler.instance)
                .withUnretained(self) // 약한참조
                .bind(onNext : { _ , _ in
                    print("바인드 코드")
                }).disposed(by: disposeBag)

debounce / throttle

  • -throttle -

  • 버튼에 API 호출 트리거가 있는 경우, lastest = false 파라미터를 통해 유저의 첫 번째 클릭만 이벤트 방출이 되게하여 API 중복 호출을 막는다.

  • 무한 스크롤(인피니티 스크롤) 구현할 때에도, 페이지 별 데이터를 가져오기 위해 API를 호출해야하기 때문에, 유저 스크롤 이벤트에 throttle을 사용하면 API Call 비용을 줄일 수 있다.

  • -debounce -

  • 연이어서 API 호출될 수 있을 때, 마지막 이벤트를 기준으로 API를 호출시킬 수 있도록 제한이 필요할 때 사용할 수 있다

profile
뭐라도 해보려는 사람

0개의 댓글