๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐ŸŽ iOS

[RxSwift] Traits ์™€ side effect & Subject ๊ธฐ๋ณธ

by ํ‹ด๋”” 2022. 1. 7.
728x90
๋ฐ˜์‘ํ˜•

Traits

traits์€ ๊ธฐ์กด Observable ๋ณด๋‹ค ์ข€๋” ์ž‘์€ ๋ฒ”์œ„์˜ ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ํ•˜๋Š” Observable ์ด๋‹ค ํ•„์ˆ˜๋กœ ์•Œ์•„์•ผ ํ•˜๋Š” ๊ฐœ๋…์€ ์•„๋‹ˆ๋‹ค

ํ•˜์ง€๋งŒ ๋‚ด๊ฐ€ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ๋ณผ๋•Œ ์ข€๋” ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ์€ ์•„๋‹ˆ๋ž€ ๋ง์”€

Single : .success(value) == .nextํ˜น์€ .error == .completed ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•œ๋‹ค ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œ ํ•˜๊ฑฐ๋‚˜ ๋””์Šคํฌ๋กœ ๋ถ€ํ„ฐ ๋กœ๋”ฉ์ด ๊ฑธ๋ฆด ๋•Œ ์‚ฌ์šฉ๋˜๋‚˜ ๋ณด๋‹ค

Completable .completed ํ˜น์€ .error ์ด๋ฒคํŠธ๋ฅผ ๋ฐ˜ํ™˜. ์–ด๋– ํ•œ ๊ฐ’๋„ ๋ฐฉ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋งŒ์•ฝ์— ์˜ค์ง ์„ฑ๊ณต๊ณผ ์‹คํŒจ๋กœ ๋๋‚˜๋Š” ์˜คํผ๋ ˆ์ดํ„ฐ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ํŒŒ์ผ์„ ์ฝ๊ณ  ๊ทธ๊ฒƒ์ด ์„ฑ๊ณตํ–ˆ๋Š”์ง€ ์•ˆํ–ˆ๋Š”์ง€ ๋ฐฉ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

Maybe single๊ณผ completable ์„ ๋ชจ๋‘ ๋ฐฉ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค. succeed์™€ fail๋„ ๊ฐ€๋Šฅํ•˜๊ณ  ๊ฐ’๊ณผ ํ•จ๊ป˜ success๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. 

 

์˜ค์ง ์ฝ๊ธฐ ์œ„ํ•œ ์˜ต์ €๋ฒ„๋ธ” ์‹œํ€€์Šค ํ”„๋กœํผํ‹ฐ๋ฅผ struct๋กœ ์›Œ๋ ˆํ•‘ ํ•ด์„œ ์‹ฌํ”Œํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค

์˜ต์…”๋„์ธ ์ด์œ ๊ฐ€ ๊ผญ Traits๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„ ๋‹ค๋ฅธ operator์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ ์™œ Traits๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š๋ƒ?

 

์‰ฝ๊ฒŒ ์‹œํ€€์Šค๋ฅผ ์ „๋‹ฌํ•˜๊ณ  ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ๊ฐ ํŠน๋ณ„ํ™”๋œ ํŠน์ง•๊ณผ ๊ตฌ์ฒด์ ์ธ ๋ถ€๋ถ„์ด ์žˆ์–ด์„œ ๊ตฌํ˜„ํ•˜๊ณ ์ž ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ž˜ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐœ๋ฐœ์ž์˜ ์˜๋„๋ฅผ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์™€ ์‰ฝ๊ฒŒ ๊ณต์œ  ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค(์–ธ์ œ๋‚˜ ๋Š๋ผ๋Š” ๊ฒƒ์ด์ง€๋งŒ ๊ฐ™์ด Rx์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ์ถฉ๋ถ„ํ•  ๋•Œ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์™€์˜ ์†Œํ†ต์ด ์›ํ™œํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค ๋‚˜๋Š” Rx์ธ๋ฐ ๋‹ค๋ฅธ ํŒ€์›์ด Rx ์ฝ”๋“œ๋ฅผ ๋ณธ๋‹ค? ๊ทธ๊ฑด ์†Œํ†ต์ด ์•ˆ๋˜๋Š” ๊ฒƒ์ž„. ์ฝ”๋“œ๊ฐ€ ์•„๋ฌด๋ฆฌ ์ข‹์•„๋„ ์˜์‚ฌ์†Œํ†ต๋„ ์ค‘์š”ํ•˜๋‹ค)

 

Single

success์™€ error ๋‘๊ฐœ์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ณ  success์ผ ๋•Œ๋Š” ํ•˜๋‚˜์˜ element๋ฅผ ๋ฐฉ์ถœํ•˜๋Š” traits ์ด๋‹ค

๋„คํŠธ์›Œํฌ ํ†ต์‹ ์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜ค๊ฑฐ๋‚˜ ๊ฒฝ๋กœ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ์ฝ์–ด ๋“ค์ผ ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค ์„ฑ๊ณตํ•˜๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ(single element)๋ฅผ ์‹คํŒจํ•˜๋ฉด .error(NotFound)๋ฅผ ๋ฐฉ์ถœํ•˜๋ฉด ๋œ๋‹ค

๊ธฐ์–ตํ•  ๊ฒƒ์€ success ์ผ๋•Œ ํ•˜๋‚˜์˜ element ์•„๋‹ˆ๋ฉด error์„ ๋ฐฉ์ถœํ•˜๋ฉด ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค

๊ทธ๋Ÿฐ๋ฐ error ์—์„œ ๋นจ๊ฐ„ ์ค„ ๊ทธ์ด๋Š”๋ฐ ํ•œ๋ฒˆ ์‚ดํŽด๋ณด๋ฉด

 

๊ฒฐ๊ตญ SingleEvent๋Š” Result๋กœ ๋˜์–ด ์žˆ๋Š”๋ฐ .success์™€ .failure๋ผ .error ์“ฐ๋ฉด ๋นŒ๋“œ๊ฐ€ ์•ˆ๋˜์—ˆ๋˜ ๊ฒƒ.

import UIKit
import RxSwift

public enum NetworkError: Error {
    case networkingFailed
}

class TraitsViewController: UIViewController {
    
    var isDataDownloaded = true

    override func viewDidLoad() {
        super.viewDidLoad()

        let disposeBag = DisposeBag()
        
        loadText(from: "test")
            .subscribe { element in
                print(element)
            } onFailure: { error in
                print(error)
            } onDisposed: {
                print("dispossed")
            }.disposed(by: disposeBag)

    }
    
    func loadText(from name: String) -> Single<String> {
        return Single.create { single in
            
            if self.isDataDownloaded {
                // ๋‹ค์šด๋กœ๋“œ ์™„๋ฃŒ์‹œ
                single(.success("์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒด๋จ"))
            } else {
                single(.failure(NetworkError.networkingFailed))
            }
            
            return Disposables.create()
        }
    }


}

 

Single์—์„œ success๋Š” .next + .complete์˜ ์˜๋ฏธ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ ์ด๋Š” .complete๋ฅผ ์˜๋ฏธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค traits๊ฐ€ observable๋ณด๋‹ค ์ข์€ ๋ฒ”์œ„์ด๊ธฐ ๋•Œ๋ฌธ์— Single์€  .complete ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•  ์ˆ˜ ์—†๋‹ค!

๋„คํŠธ์›Œํ‚น ํ†ต์‹ ํ•  ๋•Œ ์‹ฑ๊ธ€ํ†ค์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์‹ฑ๊ธ€ํ†ค์•ˆ์— ๋„คํŠธ์›Œํ‚น ํ•˜๋Š” ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜๊ฐ’์„ Single ๋กœ ๋งŒ๋“ค๋ฉด subscribe ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹น

 

Completable

ํ•˜๋‚˜์˜ element๋ฅผ ๋ฐฉ์ถœํ–ˆ๋˜ Single๊ณผ ๋‹ฌ๋ฆฌ ์•„๋ฌด๋Ÿฐ ๊ฐ’๋„ ๋ฐฉ์ถœํ•˜์ง€ ์•Š๋Š” traits ์ด๋‹ค

๊ทธ๋ž˜์„œ ๋ฐ์ดํ„ฐ ์—†์ด .completed์™€ .error ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•œ๋‹ค ์ด๋ฒคํŠธ๋กœ ๊ฒฐ๊ณผ๋งŒ ๋ฐ›์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ’์ด ์ƒ๊ด€ ์—†๋Š” ๊ณณ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ ํ›„ ์•Œ๋ฆผ์„ ๋ฐ›์„ ๋•Œ๋ผ๋˜์ง€ ๋ฐ์ดํ„ฐ๋Š” ํ•„์š” ์—†๊ณ  ๋‹ค์šด๋กœ๋“œ ๋ฐ ์—…๋ฐ์ดํŠธ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ๋˜์—ˆ๋Š”์ง€๋งŒ ํ™•์ธ ํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ(์Šคํ”Œ๋ ˆ์‹œ ๊ฐ™์€..)์—๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ๋˜๊ฒ ๋‹ค!

์•ž์„œ ์‚ดํŽด๋ณธ Single๊ณผ ๋‹ฌ๋ฆฌ  Completable์€ ์ด๋ฒคํŠธ ๋ฐฉ์ถœ์‹œ Element๊ฐ€ ์—†๋‹ค!

 

    func loadCompletable(isAvailable: Bool) -> Completable {
        return Completable.create { event in
            if isAvailable {
                event(.completed)
            } else {
                event(.error(NetworkError.networkingFailed))
            }
            
            return Disposables.create()
        }
    }
        loadCompletable(isAvailable: true)
            .subscribe { event in
                print(event)
            }.disposed(by: disposeBag)

>>> completed 

๊ฐ€ ์ฝ˜์†”์ฐฝ์— ์ฐํžŒ๋‹น

 

Maybe

Single๊ณผ Completable ๊ธฐ๋Šฅ์„ ์ˆ˜ํ–‰ ํ•  ์ˆ˜ ์žˆ๋Š” Traits ์ด๋‹ค! .success ์™€ .completed, .error ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœ ๊ฐ€๋Šฅํ•˜๋‹ค

Completable ์˜ .completed ์—์„œ์™€ ๊ฐ™์ด ์•„๋ฌด๋Ÿฐ element ์—†์ด ์ด๋ฒคํŠธ ๋ฐฉ์ถœ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค

=> ์—๋Ÿฌ ์ด๋ฒคํŠธ ๋ฐฉ์ถœ ๊ฐ€๋Šฅ or element์™€ ํ•จ๊ป˜ .success ์ด๋ฒคํŠธ ๋ฐฉ์ถœ, element ์—†์ด .completed ์ด๋ฒคํŠธ ๋ฐฉ์ถœ ๊ฐ€๋Šฅ

 

    var previousString = "old data"
    
    func loadStringWithMaybe() -> Maybe<String> {
        return Maybe.create { event in
            let newString = "new String"
            
            if self.previousString == newString {
                event(.completed)
            } else if self.previousString != newString {
                event(.success(newString))
            } else {
                event(.error(NetworkError.networkingFailed))
            }
            
            return Disposables.create {
                print("maybe disposed")
            }
        }
    }

์ „์—ญ๋ณ€์ˆ˜๋กœ ๋˜์–ด ์žˆ๋Š” previousString๊ณผ ์ƒˆ๋กœ์šด ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ .completed ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๊ณ  

๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‹ค๋ฅด๋ฉด ํ•ด๋‹น ๋ฐ์ดํ„ฐ์™€ ํ•จ๊ป˜ .success ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœํ•˜๋„๋ก ํ•œ ์ฝ”๋“œ์ด๋‹ค 

์ด ์ฝ”๋“œ๋ฅผ .success ์ด๋ฒคํŠธ์˜ element๋กœ ํ•จ๊ป˜ ๋ฐฉ์ถœํ•˜๋Š” ์ด์œ ๋Š” ๋‹ค๋ฅธ ๊ณณ์—์„œ ์—…๋ฐ์ดํŠธ ํ•˜๋ ค๊ณ  ํ•ด๋†“์€ ๊ฒƒ์ธ๋ฐ,,,

์‚ฌ์‹ค ์ด ์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ํ•ด๋„ ์ƒ๊ด€ ์—†๋Š”๋ฐ ์˜ˆ์ œ๋ฅผ ์ƒ๊ฐํ•ด ๋ณด๋‹ค๊ฐ€ ์šฐ์„  ํ…Œ์ŠคํŠธ๋งŒ ํ•ด๋ณด๊ณ ์ž ๊ฐ„๋‹จํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹น 

subscribe๋Š” ์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค

        loadStringWithMaybe()
            .subscribe { maybe in
                switch maybe {
                case .success(let newData):
                    self.previousString = newData
                    print(self.previousString)
                case .error(let error):
                    print(error)
                case .completed:
                    print("completed maybe")
                }
            }
            .disposed(by: disposeBag)

.success์—์„œ๋งŒ element๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค!

 

Do 

side effect

do()๋กœ event๋ฅผ ์ฐ์–ด๋ณด๋ฉด์„œ ๋””๋ฒ„๊น… ๊ฐ€๋Šฅ

์ถœ์ฒ˜&amp;nbsp;https://reactivex.io/

์ด๋Ÿฐ ์‹์œผ๋กœ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ ๋ ๋•Œ ๋งˆ๋‹ค Do์—์„œ ์ •์˜ํ•ด์„œ ๊ฐ’์„ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค

๋””๋ฒ„๊น… ํ•  ๋•Œ print๋กœ ์ฐ์–ด ๋ณผ ์ˆ˜ ์žˆ์Œ

.next ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค do๊ฐ€ ํ˜ธ์ถœ ๋จ

side effet๋ž€  observable ๋ฐ–์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ด๋ณด๋‚ด๋Š” ํ–‰์œ„๋ฅผ ๋งํ•˜๋Š”๋ฐ

์‹œํ€€์Šค์—์„œ next๋กœ ์—ฌ๋Ÿฌ event๋“ค์ด ๋ฐฉ์ถœ๋˜๋ฉด ์ค‘๊ฐ„ ์ค‘๊ฐ„ ๊ฐ’์„ ์บ์น˜ํ•ด์„œ ์“ฐ๋‚˜๋ณด๋‹ค ์›๋ž˜ ๋ชฉ์ ์œผ๋กœ ์“ฐ์ด์ง€ ์•Š๊ณ  ๋ถ€์ž‘์šฉ์„ ์ผ์œผํ‚ค๋Š”๊ฒŒ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋Š”๋ฐ

์›๋ž˜ Observable ์ฒ˜๋Ÿผ ์“ฐ์ด์ง€ ์•Š๊ณ  side๋กœ ์“ฐ์—ฌ์„œ ๊ทธ๋Ÿฐ๊ฑธ๊นŒ?

side effect๋ฅผ ํ†ตํ•ด์„œ ์ฝ”๋“œ ํ˜„์žฌ ํ๋ฆ„ ํ™•์ธ ๊ฐ€๋Šฅ, ๋ฉ”์†Œ๋“œ ์‹คํ–‰๋˜๊ธฐ ์ „์— ์ž‘์—… ์ง€์ •๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์Œ

 

        let disposeBag = DisposeBag()
        
        Observable.of(1, 2, 3)
            .do(onNext: { element in
                print("์˜ต์ €๋น™ do : \(element)")
            })
            .subscribe(onNext: {
                print("next event : \($0)")
            })
            .disposed(by: disposeBag)

 

์˜ต์ €๋น™ do : 1
next event : 1
์˜ต์ €๋น™ do : 2
next event : 2
์˜ต์ €๋น™ do : 3
next event : 3

์ด๋ฒคํŠธ๊ฐ€ ๋ฐฉ์ถœ ๋  ๋•Œ๋งˆ๋‹ค do์—์„œ ํ•ด๋‹น ์ด๋ฒคํŠธ์˜  element์— ์›ํ•˜๋Š” ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค!

 

Subjects 

observable๊ณผ observer์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ

์ด์ „์— ๋ฐฐ์› ๋˜ Observer์™€ ๋‹ค๋ฅธ ์ ์€ multicast ๋ฐฉ์‹์ด๋ผ๋Š” ๊ฒƒ์ด๋‹ค

์—ฌ๋Ÿฌ Observer๊ฐ€ ๋™์‹œ์— ๊ตฌ๋…ํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค

๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์œผ๋กœ PublishSubject ๊ฐ€ ์žˆ๋‹น

์•„์ง ๊ณต๋ถ€ ์ค‘์ด๋ผ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋Š”๋ฐ ์ด๊ฑธ๋กœ ์•„๋งˆ ๋น„๋™๊ธฐ์ ์ธ๊ฑธ ๋™๊ธฐ์  ์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ์„ ๋ชจ์–‘์ด๋‹น

 

ํ—ท๊ฐˆ๋ฆฌ๋‹ˆ Observer์„ ๋‹ค์‹œ ๋ณด๋ฉด

        let observer = Observable.of("1", "2") // ์˜ต์ €๋ฒ„๋ธ” : ์ด๋ฒคํŠธ ์ „๋‹ฌ
        
        // ์˜ต์ €๋ฒ„๋ธ”์„ ๊ฐ์‹œํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•จ
        let subscription3 = observer.subscribe(onNext: { element in
            print("3 : \(element)")
        })
        
        let subscription4 = observer.subscribe(onNext: { element in
            print("4 : \(element)")
        })

์˜ต์ €๋ฒ„๋ธ”์„ ์ƒ์„ฑ

์˜ต์ €๋ฒ„๋ธ”์€ ์ด๋ฒคํŠธ๋ฅผ ๋ฐฉ์ถœ์‹œํ‚จ๋‹ค Observer๋Š” subscribe๋กœ ์˜ต์ €๋ฒ„๋ธ”์„ ๊ฐ์‹œํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค

์˜ต์ €๋ฒ„๋ธ”์ด ์žˆ๋‹ค -> ๊ตฌ๋…ํ–ˆ๋‹ค -> ์˜ต์ €๋ฒ„๋ธ”์˜ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•œ๋‹ค

 

์œ„ ์ฝ”๋“œ๋ฅผ ๋งˆ๋ธ” ๋‹ค์ด์–ด๊ทธ๋žจ์œผ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ์ด๋Ÿฌํ•˜๋‹น

subejct๋ž‘ ํ—ท๊ฐˆ๋ฆฌ๋ฉด ์•ˆ๋˜๋Š” ๊ฒƒ์ด ๊ฐ์ž ๊ตฌ๋…ํ–ˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ subscription3์™€ subscription 4์˜ ์‹œํ€€์Šค๋Š” ๋‹ค๋ฅด๋‹ค ๊ฐ๊ฐ ๋”ฐ๋กœ ๊ฐ„๋‹ค 1:1๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋Š” ๊ฒƒ

๊ทธ๋Ÿฐ๋ฐ subject๋Š” Subject๊ฐ€ ์žˆ๊ณ  ์ด๋ฅผ ๊ตฌ๋…ํ•˜๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ subscriber๊ฐ€ ์žˆ๋‹ค

๋‹น์—ฐํžˆ ์‹œํ€€์Šค๋Š” ๋”ฐ๋กœ ๊ฐ„๋‹ค

 

 

        let subject = PublishSubject<String>()
        subject.onNext("1") // publisher๋Š” ์žˆ์ง€๋งŒ Observer๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์•„๋ฌด๊ฒƒ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š๋Š”๋‹ค
        
        let subscriptionOne = subject
            .subscribe(onNext: { element in
                print("one : \(element)")
            })
        subject.onNext("3")
        
        let subscriptionTwo = subject
            .subscribe(onNext: { element in
                print("two : \(element)")
            })
        
        subject.onNext("2")

 

 

๋ฐ์ดํ„ฐ๋ฅผ subscriber์—๊ฒŒ ๋ฟŒ๋ ค์ค„ ์ˆ˜ ์ž‡์Œ

subscriber๋Š” subscribe ํ•œ ์‹œ์  ์ดํ›„์— ๋ฐœ์ƒ๋˜๋Š” ์ด๋ฒคํŠธ๋งŒ ์ „๋‹ฌ ๋ฐ›๋Š”๋‹ค

 

 

๋‘ ๊ทธ๋ฆผ์„ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด Observer์™€ Subject๋Š” observable์˜ ์—ญํ™œ์„ ํ•˜๊ณ 

Subject๋Š” ์—ฌ๊ธฐ์„œ Observer์˜ ์—ญํ™œ๋„ ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค

 

 

 

 

์ฐธ๊ณ  ์‚ฌ์ดํŠธ ๋ฐ ๋„์„œ 

https://medium.com/@priya_talreja/rxswift-traits-4408d66cb6ad

rxswift reactive programming with swift _ raywenderlich

ใ„ด https://www.raywenderlich.com/books/rxswift-reactive-programming-with-swift

https://velog.io/@sangjin98/iOS-RxSwift-Observable-Disposable 

ใ„ด side effect ์žฅ์  ์ฐธ๊ณ 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€