자바스크립트의 동작 원리

hyun·2022년 3월 31일
1

JS 

목록 보기
2/5
post-thumbnail

이 포스트에서 다룰 것

우리가 작성하는 HTML, CSS, JS는 크롬과 같은 웹브라우저가 해석하고 실행해 준다. 그런데 그 중에 자바스크립트는 실행 순서가 조금 이상할 때가 있다.

실험

# python
print(1)
time.sleep(1)
print(2)

1을 출력한 후 1초를 기다린 후 2를 출력하는 코드를 파이썬으로 작성해보았다. 의도한 대로 1이 출력된 후 1초 후에 2가 출력되는 결과를 얻을 수 있다.

// js 
console.log(1);
setTimeOut(function(){console.log(2)}, 1000);
console.log(3);

파이썬 코드와 똑같은 코드를 js로 작성해보았다(3까지 추가). 그런데 이 코드를 실행하면, 예상과는 다르게 1, 3 그리고 2가 출력된다. 이번 포스트에서는 그 이유를 알아볼 것이다.

실행 순서

# python
print(1) # 1 출력
time.sleep(1) # 1초 대기 후
print(2) # 2 출력

일반적인 프로그래밍 언어는 아래의 과정을 거쳐 1,2,3이 순서대로 출력될 것이다.

  • 1을 출력
  • 1초를 기다린 후 2를 출력
  • 3을 출력
// js 
console.log(1); // 1등으로 실행
setTimeOut(function(){console.log(2)}, 1000); // 1초 후 3등으로 실행
console.log(3); // 1초 기다리는 동안 2등으로 실행 

그런데 자바스크립트는,

  • 1을 출력
  • 1초를 기다리는동안 3을 먼저 출력
  • 1초 후 2를 출력

위의 과정을 거쳐 1,3,2의 이상한(?) 실행결과를 얻게 되는 것이다.

스택과 이벤트 큐

이런 이상한 실행 결과는 스택과 이벤트 큐라는 개념으로 설명할 수 있다. 자바스크립트를 해석하고 실행해주는 웹 브라우저에는 스택이라는 공간이 있다. 코드를 스택 공간에 한 줄씩 넣어서 넣고, 한 줄씩 실행을 해 준다. 그림으로 표현하면 이렇게 되겠다.

console.log(i)와 같이 변수가 필요한 때에는, 변수를 저장해두는 힙 공간에서 변수를 가져다 쓰면서 스택 공간의 코드를 한 줄씩 실행해 나간다. 그런데, 스택은 단 하나밖에 없어서 한 번에 코드 한 줄 밖에 실행을 하지 못한다. 그래서 자바스크립트를 Single Threaded Language라고 한다.

스택 공간에 setTimeOut과 같이, 바로 실행을 할 수 없는 코드가 들어오면 어떻게 될까? 자바스크립트는 이런 코드들을 대기실로 잠깐 보내두고, 당장 실행할 수 있는 코드만 스택 공간에 남겨둔다. 한번에 한 줄씩밖에 처리를 하지 못하기 때문에 시간이 걸리는 코드는 대기실에서 대기시키는 것이다.

이렇게 대기시키는 코드들은 Ajax 요청, setTimeOut, 이벤트 리스너 등이 있다. 이제 1초가 지난 후에 대기실에 있던 코드를 다시 스택으로 옮기는데, 스택으로 바로 옮기지 않고 큐(콜백 큐, 이벤트 큐라고도 한다)로 옮긴다. 스택은 바쁜 공간이기 때문에 큐에서 2차 대기를 하는 것이다.

스택 구역에 있던 모든 코드들이 실행되어서 스택이 비게 되면, 큐에서 대기하고 있던 코드가 스택 구역으로 이동해 실행된다.

정리

  • 자바스크립트는 싱글스레드 언어로 한 번에 하나의 코드만 실행할 수 있다.
  • 브라우저 내부에는 변수를 저장하는 힙 공간, 코드를 수행하는 스택 공간, 그리고 시간이 걸리는 코드가 대기하는 큐 공간이 있다.
  • 스택은 필요하다면 힙에 있는 변수를 참조해 가며 한 줄씩 코드를 처리한다.
  • Ajax 요청, setTimeOut, 이벤트 리스너와 같이 시간이 걸리는 코드들은 스택이 아니라 대기실로 이동한다.
  • 설정한 시간을 기다린 후, 혹은 요청에 대한 응답이 온 후 실행해야 하는 코드들은 이벤트 큐로 이동한다.
  • 이벤트 큐에 있던 대기 코드들은 스택이 텅 빈 후에 스택으로 이동해 실행된다.
  • 스택은 바쁜 구역이기 때문에 복잡한 계산 같은 작업을 수행하지 않는 것이 좋다. 예를 들어 스택에서 10초가 걸리는 연산을 수행한다면, 사용자가 그동안 버튼을 눌러도 아무 반응이 일어나지 않을 것이다.
profile
프론트엔드를 공부하고 있습니다.

1개의 댓글

comment-user-thumbnail
2022년 3월 31일

이벤트 루프와 관련된 내용이군요! 좋은 내용입니다 ㅎㅎ

답글 달기