RxSwift 정리 3 - operators(.flatMap .flatMapLatest .materialize .dematerialize .share)

2021. 8. 20. 17:40Developer.TokkiSea/Apple

반응형

계속 해서 연산자 입니다.

 

.flatMap()

모든 시퀸스를 하나의 시퀸스로 모아서 발생 시킨다.

 

.flatMapLatest()

가장 마지막의 시퀸스로 발생 시킨다.

.materialize(), .dematerialize()

 

score 는 Int 이다. materialize() 를 붙여주면

RxSwift.Event<Int> 형태로 바꾸어 준다. ( ".next(1)" 이 찍힘 )

Error, Complete 등 이벤트를 확인 할 수 있다.

.dematerialize() 를 붙여주면 다시 Int 로 바뀐다. ( 다시 "1" 이 찍힘 )

 

struct Student {
    var score: ReplaySubject<Int>
}
    
let A = Student(score: ReplaySubject<Int>.createUnbounded())
let B = Student(score: ReplaySubject<Int>.createUnbounded())
let student = PublishSubject<Student>()
let studentLatest = PublishSubject<Student>()

student.flatMap {
    $0.score.materialize()
}
.filter {
    guard $0.error == nil else {
        print("N>\($0.error!)\n")
        return false
    }
    return true
}
.dematerialize()
.subscribe(onNext: {
    print("N>\($0)\n")
})
.disposed(by: disposeBag)

studentLatest.flatMapLatest {
    $0.score
}
.subscribe(onNext: {
    print("L>\($0)\n")
})
.disposed(by: disposeBag)

A.score.onNext(1) // A에 1을 발생
student.onNext(A) // student에 시퀸스 A를 포함 // ReplaySubject 때문에 즉시 N>1이 발생
student.onNext(B) // student에 시퀸스 B를 포함
A.score.onNext(2) // N>2 발생 (A:1,2)
A.score.onNext(3) // N>3 발생 (A:1,2,3)
B.score.onNext(4) // N>4 발생 (B:4)
B.score.onNext(5) // N>5 발생 (B:4,5)

studentLatest.onNext(A) // subdentLatest에 시퀸스를 A로 지정 // ReplaySubject 때문에 즉시 L>1,2,3이 발생
A.score.onNext(6) // N>6 발생 , L>6 발생 (A:1,2,3,6)
studentLatest.onNext(B) // subdentLatest에 시퀸스를 B로 지정 // ReplaySubject 때문에 즉시 L>4,5가 발생
A.score.onNext(7) // N>7 발생 , L>은 발생하지 않음. (A:1,2,3,6,7)
B.score.onNext(8) // N>8 발생 , L>8 발생 (B:4,5,8)

B.score.onError(MyError.anError) 
        // N>anError 출력 .filter 로 걸러서 에러가 무시된다.
        // L>은 "Unhandled error happened: anError" 발생
B.score.onNext(9) // N> 발생하지 않음(B시퀸스가 에러로 종료됨) , L>도 발생하지 않음. (B:4,5,8,9)
A.score.onNext(10) // N>10 발생 , L>은 발생하지 않음. (A:1,2,3,6,7,10)
studentLatest.onNext(A) // studentLatest 는 error 에 의해 종료되어서 더이상 동작하지 않음.

.share()

share(replay: , scope: .whileConnected)

replay: 는 갱신 회수

scope: 는 .whileConnected 는 Subscribe 가 있는동안 버퍼를 가지고 있고

.forever 는 상관없이 계속 가지고 있는다.

아래 네트워크 코드의 예시를 보면

Observable를 생성할때마다 네트워크 접속하여

데이터를 가져오고 생성한다.

하지만 .share() // default : .whileConnected 를 사용하면

무분별한 네트워크 접속을 막을 수 있다.

하지만 갱신이 필요할때 어떻게 해야 할지의 숙제가 남아 있다.

Observable.create {  emitter in
    let task = URLSession.shared.dataTask(with: url!) {
        ResData, res, error in if let error = error {
            emitter.onError(error)
            return
        }
        let decoder = JSONDecoder()
        if let data = ResData, let pageData = try? decoder.decode(DataModel.self, from: data) {
            emitter.onNext(pageData)
            emitter.onCompleted()
        } else {
            emitter.onCompleted()
        }
    }
    task.resume()
    return Disposables.create {
    }
}.share()

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형