iOS/Swift실전

RxSwift 파헤치기 도전! (2) Observable

Sweetft 2023. 1. 17. 15:49

실습에 들어가기 전, Rx의 심장이라는 Observable에 대해 알아보자!

- Observable = Observable Sequence = Sequence

- Asynchronous(비동기적)

- Observable은 일정 기간 동안 계속해서 이벤트를 생성하며, 이러한 과정을 emitting(방출)이라고 표현한다.

- marble diagram 시간의 흐름에 따라 값을 표시하는 방식(시간의 흐름은 왼쪽 -> 오른쪽)

    http://rxmarbles.com/

 

RxMarbles: Interactive diagrams of Rx Observables

 

rxmarbles.com

 

 

(생명주기) Obeservable은

 

 

1. 어떤 구성요소를 가지는 next 이벤트를 계속해 방출할 수 있다.

2. error 이벤트를 방출해 완전 종료될 수 있다.

3. complete 이벤트를 방출하여 완전 종료될 수 있다.

 

Observable의 메서드

import UIKit
import RxSwift

print("****  just  ****")
//하나의  엘레먼트를 를 방출하는 observable
Observable<Int>.just(1)
    .subscribe(onNext: {
        print($0)
    })

print("****  of  ****")
//하나 이상의 엘레먼트 방출
Observable<Int>.of(1, 2, 3, 4, 5)
    .subscribe(onNext: {
        print($0)
    })
Observable.of([1, 2, 3, 4, 5]) //타입 추론 가능, array를 넣을 경우 just 연산자 처럼 사용 가능
    .subscribe(onNext: {
        print($0)
    })
    
print("****  from  ****")
Observable.from([1, 2, 3]) //array만 가능, array로 방출하지 않고 요소 하나씩 방출함
    .subscribe(onNext: {
        print($0)
    })

// observable은 그냥 sequence 정의임. 구독(subscribe) 전에는 아무 이벤트도 방출하지 않음.
print("****  subscribe  ****")
Observable.of(1, 2, 3)
    .subscribe{
        print($0)
    }
Observable.of(1, 2, 3)
    .subscribe{
        if let element = $0.element {
            print(element)
        }
    }
Observable.of(1, 2, 3)
    .subscribe(onNext: {
        print($0)
    })

print("****  empty  ****")
//아무런 엘리먼트 없음. 즉시 종료할 수 있는 옵저버블 리턴하고 싶을 때, 0개의 값을 리턴하고 싶을 때 사용함.
Observable.empty()
    .subscribe {
        print($0)
    }

print("****  never  ****")
//작동은 하지만 아무것도 내뱉지 않음
Observable.never()
    //.debug("never")
    .subscribe(
        onNext: {
            print($0)
        },
        onCompleted: {
            print("completed") //출력안됨
        }
    )


print("****  range  ****")
//array를 start 부터 count 크기 만큼 값을 가짐
Observable.range(start: 1, count: 9)
    .subscribe(onNext: {
        print("2*\($0)=\(2*$0)")
    })

print("****  dispose  ****")
//observable 구독 취소
Observable.of(1, 2, 3)
    .subscribe(onNext: {
        print($0)
    })
    .dispose()

print("****  disposeBag  ****")
let disposeBag = DisposeBag()
Observable.of(1, 2, 3)
    .subscribe{
        print($0)
    }
    .disposed(by: disposeBag)

print("****  create1  ****")
Observable<Int>.create { observer -> Disposable in
    observer.onNext(1)
    observer.onCompleted() //observable 종료
    observer.onNext(2) //방출안됨
    return Disposables.create()
}
.subscribe {
    print($0)
}
.disposed(by: disposeBag)

print("****  create2  ****")
enum MyError: Error {
    case anError
}
Observable<Int>.create { observer -> Disposable in
    observer.onNext(1)
    observer.onError(MyError.anError)
    observer.onCompleted()
    observer.onNext(2)
    return Disposables.create()
}
.subscribe(
    onNext: {
        print($0)
    },
    onError: {
        print($0.localizedDescription)
    },
    onCompleted: {
        print("completed")
    },
    onDisposed: {
        print("disposed")
    }
)
.disposed(by: disposeBag)

print("****  deferred1  ****")
//observable을 생성할 수 있는 또다른 방식
//각 subscribe 새롭게 observable 항목 제공
Observable.deferred {
    Observable.of(1, 2, 3)
}
.subscribe {
    print($0)
}
.disposed(by: disposeBag)

print("****  deferred2  ****")
var flip: Bool = false
let fatory: Observable<String> = Observable.deferred {
    flip = !flip
    
    if flip {
        return Observable.of("hi")
    } else {
        return Observable.of("bye")
    }
}
for _ in 0...3 {
    fatory.subscribe(onNext: {
        print($0)
    })
    .disposed(by: disposeBag)
}

 

<참고>

패스트캠퍼스 온라인 강의