한 박자 느린 박치 이벤트 keydown에 대하여

    반응형

     

    이 문제를 발견하게 된 것은 구글 폰트 사이트와 같이 인풋에서 타이핑을 치면 각 폰트 박스에 타이핑 치는 값이 출력되는 것을 만들어보고 싶었다. 만들어본 결과물이다.

     

     

    처음에 만들때는 그저 인풋 값에 keydown 이벤트를 주고 리덕스(vanilla js에서 redux 사용해보기 연습 중이었음)를 사용해 값을 바꿔주면 될 것이라 생각했다.

     

    인풋에 준 코드

    하지만 동작은 내 기대와는 전혀 다르게 작동했다.

     

    keydown 이벤트에 setTimeout 없이 했을 때

     

    아니 뭔데요..저 6까지 쳤잖아요.. 근데 왜 5까지 밖에 안 나오냐고요;; 그래서 도대체 뭐가 문제인지 해결 방법을 찾던 중 setTimeout을 준다면 해결이 된다는 글을 봤다.

     

    setTimeout을 준 코드

    setTimeout을 주니까 그제서야 박자를 맞추는 keydown 이벤트 후,,,

     

    setTimeout을 줬을 때 결과물

     

    이 말고도 keydown 이벤트가 아닌 input 이벤트로 코드를 짜면 해결 가능하다. setTimeout 쓰기 싫으면 input을 사용해서 해보시길!!

     

    keydown 대신 input을 준 코드
    input 이벤트를 줬을 때 결과물

     

    아니 그래서 이게 왜 일어나는데?? 너무 궁금했다.

     

     

    결론부터 말하자면 keydown 이벤트가 input 이벤트보다 먼저 실행이 되어서 input이 변하기 전의 value 값을 전달해줘서 한 박자 느리게 실행된다고 한다.

     

    위 코드는 input에 입력이 되면 각 문구가 console에 찍히게 해 놓은 예제이다.

     

    입력했을 때 콘솔 창

    위의 결과 값을 보게되면 keydown event가 input event보다 먼저 찍히게 되고, setTimeout keydown event는 가장 마지막에 찍히게 된다.

     

    그래서 input 이벤트를 사용하거나, setTimeout을 사용한 keydown 이벤트를 사용하면 한 박자 느리게 반응하는 문제를 해결할 수 있었던 것이다.

     

    여기서 setTimeout이 왜 가장 마지막에 나오는지에 대해서도 역시 궁금했는데 이는 비동기 프로그래밍과 연관이 있다.

     

    간단히 설명하자면 setTimeout이나 setInterval과 같은 비동기 함수는 태스크 큐에 보관되는데 태스크 큐에 보관되어 있는 비동기 함수들은 콜 스택이 비어 있음이 감지돼야 콜 스택에 푸시가 된다. 즉, 다른 함수들이 모두 종료되면 그때서야 콜 스택에 푸시되어 실행되기 때문에 위에서 setTimeout을 사용한 setTimeout keydown event가 가장 늦게 나오는 것이다.

    반응형

    댓글