이번 포스팅에서는 로직에서 아주 간단히 사용할 수 있는 Debouncer를 만들어 사용해보겠습니다 🙋🏻
No Combine, No RxSwift
Combine이나 RxSwift에서 흔히 접할 수 있는 debounce의 사용과 혼동할 수 있어서 한번 짚고 넘어가볼께요.
예시로 애플 공식문서의 Combine 코드를 조금 더 알기 쉽게 변경하여 가져와보겠습니다.
let bounces:[(String,TimeInterval)] = [
("Black", 0),
("Green", 0.25), // 0.25s interval since last index
("Red", 1), // 0.75s interval since last index
("Blue", 1.25), // 0.25s interval since last index
("Orange", 1.5), // 0.25s interval since last index
("Purple", 2) // 0.5s interval since last index
]
let subject = PassthroughSubject<Int, Never>()
cancellable = subject
.debounce(for: .seconds(0.5), scheduler: RunLoop.main)
.sink { color in
print ("Received color is \(color)")
}
for bounce in bounces {
DispatchQueue.main.asyncAfter(deadline: .now() + bounce.1) {
subject.send(bounce.0)
}
}
// Received color is Green🟢
// Received color is Orange🟠
// Received color is Purple🟣
해당 코드를 살펴보면 bounces로 정해진 값들이 존재하죠.
그리고 PassthroughSubject 타입으로 subject를 만들고 이 subject에 debounce를 0.5초로 걸어줍니다.
그럼 해당 subject에 여러번 send되어도 마지막으로 들어온 값에 대해 0.5초 텀이 있기전에는 무시되게 막아주죠.
그 예시를 for문을 통해 구현된것을 스텝을 통해 설명해볼께요!
1️⃣ 비동기로 현재 시간에서 들어온 bounce 인자들의 정해진 TimeInterval 수치만큼 실행 지연
2️⃣ 지연된 시간 후 bounce의 Int 인자 방출
3️⃣subject에서 debounce로 0.5초가 걸려있기에 최근 방출된 값으로부터 0.5초가 지나기 전 다른 값이 방출되어 들어오면 로직 미실행
4️⃣ 0.5초동안 다른 방출이 없으면 로직 실행
이 순서인데요.
조금 말로하면 헷갈리죠!?
차근차근 한번 해당 예시 코드로 어떻게 주고 받는건지 살펴볼까요?
텍스트보단 흐름을 이해할 수 있도록 정리해봤습니다 🙋🏻
핵심은 디스패치큐에서 지연된 시간 후 각 인자들을 실행하는데 다음 인자가 들어올때 이 지연된 시간텀이 디바운스로 걸어둔 0.5초 이내이면 이전 값은 방출되지 않고 0.5초 후 들어오면 이전 값이 방출되는것입니다.
뭔가 오늘 핵심이 Combine의 debounce를 말하려는건 아니였는데 어쩌다보니 조금 자세히 말하게 되었네요!