[javascript] 중복클릭 방지 - 세마포어 이용하기

중복클릭 방지가 필요한 이유

  • 중복된 클릭으로 인한 요청은 원하는대로 에플리케이션이 의도한대로 동작할수 없게 할 뿐 아니라 데이터의 정합성을 해칠 수 있음.
  • 물론 이를 막기위해 backend는 중복된 요청이 오더라도 데이터의 정합성에 이상이 없더록 처리가 되어야함
  • front end 또한 중복된 요청이 가지않도록 인터페이스에서부터 막을 필요가 있음
  • 중복 클릭 방지라는것은 경합상황에서 한번만 수행되도록 하는것!

예시

대표적으로는 데이터를 등록하거나 수정하는 버튼이 있고, 이 이벤트가 연속으로 발생하는 경우이다.
이때 사용자의 액션이나 네트워크 이슈등의 원인이 겹쳐서 중복으로 요청이 수행될 수 있다.

javascript 에서 중복된 요청을 막는 방법을 알아보자.

일반적인 해결법 - flag

일반적으로 아래처럼 flag를 두는 방법이있다.
하지만 경합상황에서는 (특히 네트워크가 안좋은상황에서) 중복으로 doSomthing();이 실행되는 현상이 발생한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
var isDisabled = false;

$('#button').click(function () {

if (isDisabled) { //<-( 1 ) 수행가능여부 검사
alert("이미 작업이 수행중입니다.");
return false;
} else {
isDisabled = true; //<-( 2 ) 실행 불가능하도록 flag 변경
doSomthing();
isDisable = false; //(3)수행가능하도록 열어준다. settimeout을통해 X초 뒤에 풀어주는것도 방법이다.
}
});
  • 만약 (3)의 코드를 사용하지 않는다면 1회만 기능을 수행하도록 막게된다.
  • (3) 에서 setTimeout() 을 사용하면 일정시간 후에 풀어주도록 구현할수있다.

Semaphore로 중복 방지하기

세마포어를 활용한다. 운영체제에서도 사용하는 방법이다.
동시에 접근하더라도 작업 수행여부를 판별하기전에 횟수를 제한한다.
1로 설정을 하면 2회이상 동시에 접근이 되는것을 막을 수 있다.
flag와 다른점은 횟수를 다르게 설정할수 있다는 점이다.

작업이 끝난 후 다시 접근이 가능하게 하려면 count를 증가시켜준다.
위에서 언급하였드시 카운트를 복구하지 않으면 총 사용횟수만 제어할 수 있고, 일정시간 후에 회복 시키는것도 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var acceessableCount = 1; //동시접근제한수, 리소스에따라 변경가능

$('#button').click(function () {

acceessableCount = acceessableCount -1; //count부터 뺀다

if (acceessableCount <= 0 ) {
alert("이미 작업이 수행중입니다.");
} else {
doSomthing();
}

acceessableCount = acceessableCount +1; //작업이 끝난 후 다시 작업할수 있게하려면 +1을 한다. 회복시키지 않으면 코드제거.

});

세마포어 관련글 : https://namu.wiki/w/세마포어

Comments