Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
#️⃣ 연관된 이슈
⏰ 작업 시간
📝 작업 내용
📸 스크린샷
📒 리뷰 노트
학습 목표
사용자 경험 증대를 위한 Debounce와 Throttle 개념을 익히고,
본 예제에서는 위 내용을 통해 버튼 중복 클릭을 방지하고자 한다.
학습 내용
개요
기록소 프로젝트에서 “책 만들기” 버튼이 여러 번 클릭되어 하나의 책만 만들어져야 하는데, 여러 개의 책이 만들어지는 것을 보았다.
다른 버튼도 ?! 해서 막 눌러보니 다른 버튼들도 마찬가지였다.
중복으로 버튼이 눌리는 것을 방지하기 위해 머리속으로 생각해보면,
버튼이 눌린 순간, 0.N초간 여러 번 눌리더라도 한 개만 처리하면 될 것 같다.
그래서 요즘은 반응형 프로그래밍을 위한 프레임워크들, Combine이나 RxSwift에서 Debounce와 Throttle이라는 오퍼레이터를 제공해준다.
우리는 이 오퍼레이터를 통해서 이벤트 방출을 제어할 수 있다.
중복 버튼 눌림을 위한 방법
1. Debounce
텍스트필드에 Debounce를 3초로 걸었다고 가정해보자.
그럼 사용자가 더 이상 입력하지 않는 시점부터
3초 후
에 이벤트를 발행한다.Apple을 입력할 건데 각 알파벳을 2초마다 입력한다면,
A → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨
Ap → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨
…
Appl → 2초 → e 입력 = 3초 안 지남 = 이벤트 발송 안 됨
Apple 입력 끝 → 3초 후 이벤트 발송
2. Throttle
위 Debounce와 다르게 Throttle은 일정 기간 동안에는 한 번만 이벤트가 발생하도록 제한한다.
이때 이벤트 발생을 가장 마지막, 즉 최근에 들어온 이벤트를 방출할 지 말지를 lastest 파라미터를 통해 선택할 수 있다.
같은 예제로 보자면,
A → 2초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨
Ap → 1초 → 3초지남 = 이벤트 발송
Ap → 1초 → p 입력 = 3초 안 지남 = 이벤트 발송 안 됨
App → 2초 → 3초 지남 = 이벤트 발송됨 → l 입력
…
이런 느낌이다.
스로틀과 디바운스의 차이는 일정 시간 간격으로 마지막 이벤트를 방출해주는 차이.
3. 반응형 프로그래밍을 위한 프레임워크가 없었던 시절은?
Combine가 없던 iOS 13버전 이전이나, RxSwift가 없던 때에는 어떻게 했을 지 궁금해서 고민해봤다. 아마 버튼 자체를 못 누르게 하거나, 시간을 직접 제어하지 않았을까?
버튼을 탭하면 즉시
isEnabled = false
로 만든다거나isUserInteractionEnable = false
를 설정하고, 로직이 끝나면 true로 만드는 게 있을 것 같다.또, Date()를 시작해서 시간을 직접 비교하는 게 있을듯 하다.
Gㅛ수PT님도 그렇게 말하시긴 하네요
기록소 프로젝트에 적용
악의적으로 버튼을 광클하는 유저가 있을 수도 있고, 한 번 클릭했는데 결과가 바로 안 보여서 짧은 시간 내에 두세 번 클릭했을 수도 있다.
우리 프로젝트는 네트워크 요청을 따로 하지 않기 때문에 버튼 클릭에 따른 요청이 엄청 오래 걸리지 않는다.
위 내용을 정리하면 Debounce는 마지막 이벤트 후 일정 시간이 지나야 실행되도록 하는 것이고, Throttle은 일정 시간 동안 이벤트를 한 번만 허용하도록 하는 것이다.
책 만들기 버튼과 같이 사용자가 버튼을 빠르게 여러 번 누르더라도 한 번의 작업만 실행되어야 하는 상황에서는, 즉시 첫 번째 클릭에 반응하고 그 이후 짧은 시간 동안 추가 클릭은 무시하는 것이 필요하다. 이 경우에는 Throttle 방식을 선택하는 것이 적합하다고 생각했다.
Debounce는 버튼이 눌리고 더 이상 안 눌릴 때 요청을 보내는 경우 일테니까 이 경우랑은 조금 다른 것 같아 Throttle로 결정했다.
참조 링크
https://0urtrees.tistory.com/365
https://green1229.tistory.com/178
https://green1229.tistory.com/290
https://green1229.tistory.com/291