Observable, Trait ( Single, Maybe, Completable ), Subject

김영민·2022년 3월 18일
0

RxSwift

목록 보기
2/4

1. Observable = Sequence

2. 비동기적

3. 일정 기간동안 계속해서 이벤트를 생성(emit)

4. 시간의 흐름에 따라서 값을 표시하는 방식


Observable의 종류

  • just → 원소 하나만
  • of → 원소 여러 개
  • from → 오직 배열의 형태만 가짐
  • empty → 즉시 종료할 수 있는 observable, 0개의 값을 리턴하고 싶은 observable 쓰고 싶을 때 사용
  • never → 작동은 하지만 아무 것도 방출하지 않음
  • range → 범위 설정
  • create → 직접적인 코드 구현을 통해 옵저버 메서드를 호출하여 옵저버블을 생성
  • deffered → observable 안에 새로운 observable들을 만들 수 있음

subscribe : 구독의 의미로 만들어진 Observable을 방출할 수 있게 해줌

  • observable 을 subscribe 하지 않으면 실행하지 않음 (방아쇠 역할)

dispose : subscribe를 취소

  • DisposeBag → 구독하고 난 뒤 disposebag에 넣고 나중에 필요할 때 한번에 방출
  • 메모리 누수 방지에 용이

코드 예시

import UIKit
import RxSwift

print("---just---") // 원소 하나만
Observable<Int>.just(1)
    .subscribe(
        onNext: {
            print($0)
        }
    )
print("---Of---") // 원소 여러 개
Observable<Int>.of(1,2,3,4,5)
    .subscribe(
        onNext: {
            print($0)
        }
    )
print("---from---") //array 형태
Observable.from([1,2,3,4,5])
    .subscribe(
        onNext: {
            print($0)
        }
    )

Observable.range(start: 1, count: 9) //범위 
    .subscribe(
        onNext:{
            print("2 * \($0) = \(2*$0)")
        }
    )

let disposBag = DisposeBag()

// 직접적인 코드 구현을 통해 옵저버 메서드를 호출하여 옵저버블을 생성
Observable.create{ observer -> Disposable in
    observer.onNext(1)
    observer.onCompleted()
    observer.onNext(2)
    return Disposables.create()
}
.subscribe{
    print($0)
}.disposed(by: disposBag)

Trait ( Single, Maybe, Completable )

→ 좁은 범위의 Observable ( 코드 가독성을 위해 )


Single

  • 파일 저장, 다운로드, 디스크에서 데이터 로딩에 주로 사용
  • 네트워크 (JSONDecoding)
  • .success : onNext + onCompleted
  • asSingle 가능

Maybe

  • asMaybe 가능

Completable

  • 어떠한 값도 방출하지 않는다.
  • 동기식 연산의 성공 여부 확인

→ 유저가 작업할 동안 자료가 저장될 때, 저장이 완료되어 간단한 알림을 보내거나 에러가 발생했을 때 사용


코드 예시

Single

print("======single======")

struct SomeJSON : Decodable {
    let name: String
}

enum JSONError : Error {
    case decodingError
}

let json1 = """
    {"name":"park"}
"""

let json2 = """
    {"my_name":"Kim"}
"""

func decode(json: String) -> Single<SomeJSON> {
    Single<SomeJSON>.create { observer -> Disposable in
        guard let data = json.data(using: .utf8),
              let json = try? JSONDecoder().decode(SomeJSON.self,from: data)
        else {
            observer(.failure(JSONError.decodingError))
            return Disposables.create()
        }
        
        observer(.success(json))
        
        return Disposables.create()
    }
}

decode(json: json2)
    .subscribe{
        switch $0 {
        case .success(let json):
            print(json.name)
        case .failure(let error):
            print(error)
        }
    }.disposed(by: disposeBag)
  • Json decoding할 때의 single 사용

Subject

Observable이자 Observer


PublishSubject

→ 빈 상태로 시작하여 새로운 값만을 subscriber에 방출한다.

가장 상단이 PublishSubject.

첫번째 구독자는 1 이후에 subscribe 했으므로 2부터 받을 수 있다.

두번째 구독자는 2 이후에 subscribe 했으므로 3부터 받을 수 있다.


BehaviorSubject

→ 하나의 초기값을 가진 상태로 시작하여, 새로운 subscriber에게 초기값 또는 최신값을 방출한다.

가장 상단이 BehaviorSubject.

첫번째 구독자는 1 이후에 subscribe 했으므로 직전인 1부터 받을 수 있다.

두번째 구독자는 2 이후에 subscribe 했으므로 직전인 2부터 받을 수 있다.


RelaySubject

→ 버퍼를 두고 초기화하며, 버퍼 사이즈만큼의 값들을 유지하면서 새로운 subscriber에게 방출한다.

가장 상단이 RelaySubject.

버퍼사이즈가 2라고 했을 때, 두번째 구독자는 1과 2를 모두 받을 수 있다.

0개의 댓글