Skip to content

Latest commit

ย 

History

History
155 lines (129 loc) ยท 6.81 KB

Reactive Programming.md

File metadata and controls

155 lines (129 loc) ยท 6.81 KB

Reactive Programming

Reactive Programming(๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ)์ด๋ž€?

๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ๊ณผ ๋ณ€ํ™”์˜ ์ „๋‹ฌ(๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์—์„œ ๊ฐ’์ด ๋ณ€ํ–ˆ์„ ๋•Œ ์ „๋‹ฌ์ด ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒƒ)์— ๋Œ€ํ•œ ์„ ์–ธ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจ๋Ÿฌ๋‹ค์ž„

  • ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•œ ๋ฌธ์žฅ

    ๋ช…๋ นํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ a = b + c ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด b + c ์˜ ๊ฒฐ๊ณผ๊ฐ€ ํ• ๋‹น๋˜๊ณ ,
    b, c ์˜ ๊ฐ’์˜ ๋ณ€ํ™”๋Š” a์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    ๋ฐ˜๋ฉด, ๋ฆฌ์•กํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ๋Š” b ์™€ c์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค a = b + c๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ 
    ์ž๋™์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์–ด a์˜ ๊ฐ’์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ์š”์•ฝํ•˜์ž๋ฉด Reactive Programming์€ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ๋น„๋™๊ธฐ์ ์ธ ํ๋ฆ„์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ(?)์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

  • ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์–ด๋– ํ•œ ๊ธฐ๋Šฅ์„ ์ง์ ‘ ์ •ํ•ด์„œ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์‹œ์Šคํ…œ์— ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์•Œ์•„์„œ ์ฒ˜๋ฆฌ๋œ๋‹ค.

  • ๊ธฐ์กด์˜ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์„ Pull ๋ฐฉ์‹, Reactive Programming ๋ฐฉ์‹์„ Push ๋ฐฉ์‹์ด๋ผ๊ณ ๋„ ํ•œ๋‹ค.

    • Pull ๋ฐฉ์‹: ๋น„๋™๊ธฐ request๋ฅผ ๋˜์ง€๊ณ  response๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ callback์œผ๋กœ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌ
    • Push ๋ฐฉ์‹: ๋น„๋™๊ธฐ request๋ฅผ ๋˜์ง€๊ณ  ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•œ subscribe ํ˜•์‹์œผ๋กœ ๋ฐ˜์‘ํ•˜๋„๋ก ์ฒ˜๋ฆฌ
  • Reactive Programming์€ ์ฃผ๋ณ€ ํ™˜๊ฒฝ๊ณผ ๋Š์ž„์—†์ด ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜๋Š”๋ฐ, ํ”„๋กœ๊ทธ๋žจ์ด ์ฃผ๋„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํ™˜๊ฒฝ์ด ๋ณ€ํ•˜๋ฉด ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์•„ ๋™์ž‘ํ•จ์œผ๋กœ์จ ์ƒํ˜ธ์ž‘์šฉํ•œ๋‹ค.

  • ๋‹ค์–‘ํ•œ ์–ธ์–ด์—์„œ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•ด ReactiveX๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.


ReactiveX(Reactive eXtensions)๋ž€?

Rx๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ(observable) ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ๋น„๋™๊ธฐ, ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(API)

  • Observer ํŒจํ„ด์„ ํ™•์žฅํ•˜์—ฌ ๋ฐ์ดํ„ฐ ๋ฐ ์ด๋ฒคํŠธ์˜ ์‹œํ€€์Šค๋ฅผ ์ง€์›ํ•œ๋‹ค.
  • ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์Šค๋ ˆ๋”ฉ, ๋™๊ธฐํ™”, ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ, ๋™์‹œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ ๋ฐ non-blocking I/O์— ๊ด€ํ•œ ์šฐ๋ ค๋ฅผ ์ค„์ธ๋‹ค.
    • non-blocking: A ํ•จ์ˆ˜๊ฐ€ B ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ, B ํ•จ์ˆ˜๊ฐ€ ์ œ์–ด๊ถŒ์„ ๋ฐ”๋กœ A ํ•จ์ˆ˜์—๊ฒŒ ๋„˜๊ฒจ์ฃผ๋ฉด์„œ, A ํ•จ์ˆ˜๊ฐ€ ๋‹ค๋ฅธ ์ผ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ

Rx์˜ ์ž‘๋™ ๋ฐฉ์‹

  • Rx์—์„œ๋Š” Observable ๊ฐ์ฒด๋ฅผ ํ†ตํ•ด์„œ ์ด๋ฒคํŠธ์˜ ํ๋ฆ„์„ ํ‘œํ˜„ํ•œ๋‹ค.
  • ๊ทธ ํ›„, Operator๋ฅผ ํ†ตํ•ด์„œ Observable์ด ๋‚ด๋ฑ‰๋Š” ์ด๋ฒคํŠธ์˜ ๊ฐ’๋“ค์„ ํ•ด๋‹น ํ˜•ํƒœ๋กœ ์กฐํ•ฉํ•˜๊ณ  ๋ณ€๊ฒฝํ•œ๋‹ค.


Rx์˜ 3์š”์†Œ

1. Oberservable

๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ

  • ๋ณดํ†ต Observable์€ ์–ด๋– ํ•œ ์ˆœ์ฐจ์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.
  • ์ด ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ๊ด€์ฐฐํ•˜๊ฒŒ ๋˜๋Š” Observer๋“ค์€ Observer ํŒจํ„ด์„ ์‚ฌ์šฉํ•˜์—ฌ Observable์ด ๋ฐœํ–‰ํ•˜๋Š” ๋ฐ์ดํ„ฐ์— ์ฆ‰๊ฐ ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

2. Operator

Observable์˜ ์ž…๋ ฅ๋“ค์„ ์ž…๋ ฅ๋ฐ›์•„ ๊ฒฐ๊ณผ๋กœ ์ถœ๋ ฅํ•ด๋‚ด๋Š” ์—ฐ์‚ฐ์ž

  • ๋Œ€๋ถ€๋ถ„์˜ ์—ฐ์‚ฐ์ž๋Š” Observable์—์„œ ์ž‘๋™ํ•˜๊ณ  Observable์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์ด๋Ÿฌํ•œ ์—ฐ์‚ฐ์ž๋ฅผ ์ฒด์ธ์—์„œ ์ฐจ๋ก€๋กœ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Rx์—์„œ๋Š” ์ƒ์„ฑ, ๋ณ€ํ™˜, ํ•„ํ„ฐ๋ง, ๊ฒฐํ•ฉ, ์˜ค๋ฅ˜ ์ฒ˜๋ฆฌ ๋“ฑ ์ˆ˜๋งŽ์€ ์—ฐ์‚ฐ์ž๊ฐ€ ์กด์žฌํ•œ๋‹ค.

3. Schedulers

  • Observable ์—ฐ์‚ฐ์ž์— ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์„ ๋„์ž…ํ•˜๋ ค๋ฉด ํ•ด๋‹น ์—ฐ์‚ฐ์ž ๋˜๋Š” ํŠน์ • Observable์ด ํŠน์ • ์Šค์ผ€์ฅด๋Ÿฌ์—์„œ ์ž‘๋™ํ•˜๋„๋ก ์ง€์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

Rx์˜ ์ด๋ฒคํŠธ ๊ฐ์ง€

  • Observable์€ Emitter์— ํฌํ•จ๋˜์–ด ์žˆ๋Š” 3๊ฐ€์ง€ ์ด๋ฒคํŠธ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ฐ์‹œ์ž์—๊ฒŒ ์ด๋ฒคํŠธ๋ฅผ ์•Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค.
  • Observable์—์„œ ๋ฐ์ดํ„ฐ, ์˜ค๋ฅ˜ ๋“ฑ์„ ๋ฐœํ–‰ํ•  ๋•Œ null์€ ๋ฐœํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ•ญ์ƒ onComplete() ํ˜น์€ onError() ๋‘˜ ์ค‘ ํ•˜๋‚˜๋กœ๋งŒ ๋ฐ์ดํ„ฐ ๋ฐœํ–‰์ด ์ข…๋ฃŒ๋˜์–ด์•ผ ํ•œ๋‹ค.

1. onNext()

๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜ ๋ฐœํ–‰๋์Œ์„ ์•Œ๋ฆฌ๋Š” ์ด๋ฒคํŠธ

  • ์—ฐ์†๋œ ๋ฐ์ดํ„ฐ์˜ ๊ฒฝ์šฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ํ•˜๋‚˜์”ฉ ์ฐจ๋ก€๋Œ€๋กœ onNext()๋กœ ๋ฐœํ–‰๋œ๋‹ค.

2. onComplete()

๋ฐ์ดํ„ฐ ๋ฐœํ–‰์ด ๋ชจ๋‘ ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ์ด๋ฒคํŠธ

  • onComplete()๊ฐ€ ํ˜ธ์ถœ๋œ ์ดํ›„์—๋Š” ๋”์ด์ƒ onNext()๊ฐ€ ํ˜ธ์ถœ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.

3. onError()

์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ์ด๋ฒคํŠธ

  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ onError()๊ฐ€ ํ˜ธ์ถœ๋œ ์ดํ›„์—๋Š” ๋”์ด์ƒ onNext()๊ฐ€ ํ˜ธ์ถœ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.

Rx์˜ ์žฅ์ 

1. ์ด๋ฒคํŠธ ์ŠคํŠธ๋ฆผ ๋˜๋Š” ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ์‰ฝ๊ฒŒ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

2. ์ฟผ๋ฆฌ์™€ ๊ฐ™์€ ์—ฐ์‚ฐ์ž๋กœ ์ŠคํŠธ๋ฆผ์„ ์ž‘์„ฑํ•˜๊ณ  ๋ณ€ํ™˜ํ•œ๋‹ค.

3. Side effect๋ฅผ ์ผ์œผํ‚ฌ์ˆ˜ ์žˆ๋Š” ๊ด€์ฐฐ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ์ŠคํŠธ๋ฆผ์„ ๊ตฌ๋…ํ•  ์ˆ˜ ์žˆ๋‹ค.

4. ์ฝ”๋“œ ๊ด€๋ จ ์žฅ์ 

  • Functional
    ๊ด€์ธก ๊ฐ€๋Šฅํ•œ ์ŠคํŠธ๋ฆผ์„ ํ†ตํ•ด ๊น”๋”ํ•˜๊ฒŒ ์ž…/์ถœ๋ ฅ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณต์žกํ•œ ํ”„๋กœ๊ทธ๋žจ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Less is more
    ์ •๊ตํ•˜๊ณ  ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ๋ช‡ ์ค„์˜ ์ฝ”๋“œ๋กœ ์ค„์ผ์ˆ˜ ์žˆ๋‹ค.
  • Async error handling
    ์ „ํ†ต์ ์ธ try/catch๋Š” ๋น„๋™๊ธฐ ์—๋Ÿฌ๋Š” ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์ง€๋งŒ Rx๋Š” ๋น„๋™๊ธฐ ์—๋Ÿฌ๋„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.
  • Concurrency amd easy
    ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์Šค๋ ˆ๋”ฉ, ๋™๊ธฐํ™” ๋ฐ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ถ”์ƒํ™” ํ•  ์ˆ˜ ์žˆ๋‹ค.

Rx์˜ ๋‹จ์ 

1. ๋Ÿฌ๋‹์ปค๋ธŒ๊ฐ€ ๋†’์•„ ํ•™์Šต์ด ์–ด๋ ต๋‹ค.

2. ๋””๋ฒ„๊น…์ด ์–ด๋ ต๋‹ค.


RxSwift ์˜ˆ์‹œ

// ๊ธฐ์กด ์ฝ”๋“œ
Network.download(file: "https://www...")
    .subscribe(onNext: { data insequence
    	// ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
    },
    onError: { error in
    	// ์—๋Ÿฌ ํ‘œํ˜„
    },
    onCompleted: {
    	// ๋‹ค์šด๋กœ๋“œ ๋œ ํŒŒ์ผ ์‚ฌ์šฉ
    })
  • Network.download๊ฐ€ Observable
  • onNext() ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›๊ณ , onError() ์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์—๋Ÿฌ๋ฅผ ํ‘œํ˜„ํ•œ๋‹ค. onComplete() ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›์œผ๋ฉด ์•ก์…˜์„ ์ทจํ•  ์ˆ˜ ์žˆ๋‹ค.
UIDevice.rx.orientation
    .filter { value in
    	return value != .landscape
    }
    .map { _ in
    	return "์„ธ๋กœ๋ชจ๋“œ"
    }
    .subscribe(onNext: { string in
    	showAlert(text: string)
    })
  • fileter ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด orientation์ด ์„ธ๋กœ์ธ ๊ฒฝ์šฐ์—๋งŒ ํ•„๋”๋งํ•œ๋‹ค.
  • ๊ฐ€๋กœ์ธ ๊ฒฝ์šฐ์—๋Š” ์ด๋ฒคํŠธ๊ฐ€ ์•„์˜ˆ ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • map ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด string ์ถœ๋ ฅ์œผ๋กœ ๋ณ€ํ™˜๋˜๊ณ  ๋งˆ์ง€๋ง‰์œผ๋กœ subscribe()๋ฅผ ํ†ตํ•ด onNext() ์ด๋ฒคํŠธ๋ฅผ ๊ตฌ๋…ํ•œ๋‹ค.

ReactiveX๋ฅผ ์ง€์›ํ•˜๋Š” ์–ธ์–ด๋“ค

  • Java: RxJava
  • JavaScript: RxJS
  • C#: Rx.NET
  • C#(Unity): UniRx
  • Scala: RxScala
  • Clojure: RxClojure
  • C++: RxCpp
  • Lua: RxLua
  • Ruby: Rx.rb
  • Python: RxPY
  • Go: RxGo
  • Groovy: RxGroovy
  • JRuby: RxJRuby
  • Kotlin: RxKotlin
  • Swift: RxSwift
  • PHP: RxPHP
  • Elixir: reaxive
  • Dart: RxDart


Reference

[RxJava] RxJava ์ดํ•ดํ•˜๊ธฐ - 1. Reactive Programming ์ด๋ž€

ReactiveX

[Reactive X] Observable ๊ฐœ๋… ๋‚ ๋จนํ•˜๊ธฐ