TimeโBased
โฑ๏ธ TimeโBased Operators โ debounce
, throttle
, timeout
์ธ
debounce
, throttle
, timeout
์ธโ์ด๋ฒคํธ๋ฅผ ์๊ฐ ์ถ์ผ๋ก ๋ค๋ฌ์.โ
์๊ฐ ๊ธฐ๋ฐ(TimeโBased) ์คํผ๋ ์ดํฐ๋ Observable์ ๋ฐํ ๊ฐ๊ฒฉ๊ณผ ์ง์ฐ์ ์ ์ดํฉ๋๋ค. UI ์ ๋ ฅ ์ ์ด, ์์ฒญ ํญ์ฃผ ๋ฐฉ์ง, ๋คํธ์ํฌ ํ์์์ ๋ฑ์ ํ์์ ์ ๋๋ค.
1๏ธโฃ ํต์ฌ ์คํผ๋ ์ดํฐ ๋น๊ตํ
debounce
์ง์ ์๊ฐ ๋์ ์ ์ด๋ฒคํธ ์์ ๋ ๋ง์ง๋ง ๊ฐ ๋ฐฉ์ถ
dueTime, scheduler
๊ฒ์์ฐฝ ์๋์์ฑ, ํ ์คํธ ์ ๋ ฅ
throttle
์ฒซ/๋ง์ง๋ง ์ด๋ฒคํธ๋ง ํต๊ณผ (์ต์ ) โ ๊ธฐ๊ฐ ๋ด ์ค๋ณต ์ต์
dueTime, latest
๋ฒํผ ์ฐํ ๋ฐฉ์ง, API Rateโlimit
timeout
์ง์ ์๊ฐ ๋ด onNext ์์ผ๋ฉด ์๋ฌ
dueTime, scheduler, other
์๋ฒ ์๋ต ๋๊ธฐ ์ ํ
delay
๊ฐ ์ด๋ฒคํธ๋ฅผ ์ง์ ์๊ฐ ์ง์ฐ ํ ๋ฐฉ์ถ
dueTime, scheduler
์ ๋๋ฉ์ด์ ์ํ์ค, ์๋ฆผ ์ง์ฐ
sample
ํธ๋ฆฌ๊ฑฐ ์คํธ๋ฆผ/์ฃผ๊ธฐ๋ง๋ค ์ต์ ๊ฐ์ ์ํ
sampler
์ฃผ์ ์ฐจํธ Snapshot
buffer
์ผ์ ๊ธฐ๊ฐ/๊ฐ์๋ก ๋ฐฐ์น ๋ฌถ๊ธฐ
timeSpan, count
์ผ์ Batch Upload
2๏ธโฃ ์ค์ ์ค๋ํซ
A. debounce
โ ๊ฒ์์ด ์
๋ ฅ
debounce
โ ๊ฒ์์ด ์
๋ ฅsearchBar.rx.text.orEmpty
.debounce(.milliseconds(300), scheduler: MainScheduler.instance)
.distinctUntilChanged()
.flatMapLatest(api.search)
.bind(to: results)
300โฏms ๋ด ์ถ๊ฐ ์ ๋ ฅ์ด ์์ ๋๋ง ํธ์ถ โ API ํธ๋ํฝ ์ ๊ฐ
B. throttle
โ ์ข์์ ๋ฒํผ ์ค๋ณต ๋ฐฉ์ง
throttle
โ ์ข์์ ๋ฒํผ ์ค๋ณต ๋ฐฉ์งlikeButton.rx.tap
.throttle(.seconds(1), scheduler: MainScheduler.instance)
.subscribe(onNext: viewModel.like)
1โฏ์ด ์์ ์ฌ๋ฌ ํญ ์ค ์ฒซ ํญ๋ง ์ฒ๋ฆฌ (latest: false)
C. timeout
โ ์๋ฒ ์๋ต ์คํจ ์ฒ๋ฆฌ
timeout
โ ์๋ฒ ์๋ต ์คํจ ์ฒ๋ฆฌapi.fetchData()
.timeout(.seconds(5), scheduler: MainScheduler.instance)
.catchError { _ in Observable.just(.timeoutPlaceholder) }
.bind(to: viewModel.state)
D. buffer
โ ์ผ์ 10๊ฐ ์ด๋ฒคํธ ๋ฌถ์ด ์
๋ก๋
buffer
โ ์ผ์ 10๊ฐ ์ด๋ฒคํธ ๋ฌถ์ด ์
๋ก๋sensorStream
.buffer(timeSpan: .seconds(2), count: 10, scheduler: SerialDispatchQueueScheduler(qos: .utility))
.filter { !$0.isEmpty }
.flatMap(uploadBatch)
.subscribe()
3๏ธโฃ debounce vs throttle ์๊ฐ ๋น๊ต
์ด๋ฒคํธ ์คํธ๋ฆผ
โโxโxโโxโxโโโโxโโ
debounce(300โฏms)
โโโโโxโโโโโโโxโ
(๋ง์ง๋ง ๊ฐ)
throttle(300โฏms, latest:false)
โโxโโโโโxโโโโโx
(์ฒซ ๊ฐ)
throttle(300โฏms, latest:true)
โโxโโโโโโโxโโโโx
(์ฒซ+๋ง์ง๋ง)
latest
ํ๋๊ทธ๊ฐ true๋ฉด ๊ธฐ๊ฐ ๋์ ์ถ๊ฐ๋ก ์ต์ ๊ฐ ์ ๋ฌ.
4๏ธโฃ Scheduler & Testing Tips
๋๋ถ๋ถ์ ์๊ฐ ์ฐ์ฐ์ Scheduler ์์กด โ ํ์ ์
TestScheduler
๋ก ๊ฐ์ ์๊ฐ ํ ์คํธ (advanceTo
).UI ์์ ์
MainScheduler
, ๋ฐฑ๊ทธ๋ผ์ด๋ Polling์ConcurrentDispatchQueueScheduler
.
5๏ธโฃ Edge Cases & pitfalls
debounce 0โฏms ๋ ์๋ฏธ ์๊ณ , ํ๋ซํผ๋ง๋ค ์ต์ ํด์๋(์ฃผ๋ก 1โฏms).
timeout
๋คretry
์ฐ์ ์ฌ์ฉ ์ Cartesian ํญ๋ฐ ์กฐ์ฌ โ ์ง์ Backโoff ํ์.buffer
์ ํฐcount
+ ๊ธดtimeSpan
์ค์ ํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ฒํผ ์ฆ๊ฐ ์ํ.
6๏ธโฃ Mini Quiz
throttle
์latest
์ต์ ์ true๋ก ํ๋ฉด ์ด๋ค ๊ฐ์ด ์ถ๊ฐ๋ก ๋ฐฉ์ถ๋๋๊ฐ?debounce
์sample
์ ์ฐจ์ด๋ฅผ ๊ฐ๋จํ?timeout
ํ ๋ค๋ฅธ Observable๋ก ๋์ฒดํ๋ ค๋ฉด ๋ฌด์์ ์ฌ์ฉ?
์ด์ด์ โถ๏ธ errorHandling ๋ก ์ด๋ํด
catchError
,retry
๋ก ์์ ์ ์ธ ์คํธ๋ฆผ ๋ง๋ค๊ธฐ๋ฅผ ๋ฐฐ์๋ด ์๋ค. ๐
Last updated