우리가 작성하는 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이 순서대로 출력될 것이다.
// js
console.log(1); // 1등으로 실행
setTimeOut(function(){console.log(2)}, 1000); // 1초 후 3등으로 실행
console.log(3); // 1초 기다리는 동안 2등으로 실행
그런데 자바스크립트는,
위의 과정을 거쳐 1,3,2의 이상한(?) 실행결과를 얻게 되는 것이다.
이런 이상한 실행 결과는 스택과 이벤트 큐라는 개념으로 설명할 수 있다. 자바스크립트를 해석하고 실행해주는 웹 브라우저에는 스택이라는 공간이 있다. 코드를 스택 공간에 한 줄씩 넣어서 넣고, 한 줄씩 실행을 해 준다. 그림으로 표현하면 이렇게 되겠다.
console.log(i)
와 같이 변수가 필요한 때에는, 변수를 저장해두는 힙 공간에서 변수를 가져다 쓰면서 스택 공간의 코드를 한 줄씩 실행해 나간다. 그런데, 스택은 단 하나밖에 없어서 한 번에 코드 한 줄 밖에 실행을 하지 못한다. 그래서 자바스크립트를 Single Threaded Language라고 한다.
스택 공간에 setTimeOut
과 같이, 바로 실행을 할 수 없는 코드가 들어오면 어떻게 될까? 자바스크립트는 이런 코드들을 대기실로 잠깐 보내두고, 당장 실행할 수 있는 코드만 스택 공간에 남겨둔다. 한번에 한 줄씩밖에 처리를 하지 못하기 때문에 시간이 걸리는 코드는 대기실에서 대기시키는 것이다.
이렇게 대기시키는 코드들은 Ajax 요청, setTimeOut, 이벤트 리스너 등이 있다. 이제 1초가 지난 후에 대기실에 있던 코드를 다시 스택으로 옮기는데, 스택으로 바로 옮기지 않고 큐(콜백 큐, 이벤트 큐라고도 한다)로 옮긴다. 스택은 바쁜 공간이기 때문에 큐에서 2차 대기를 하는 것이다.
스택 구역에 있던 모든 코드들이 실행되어서 스택이 비게 되면, 큐에서 대기하고 있던 코드가 스택 구역으로 이동해 실행된다.
이벤트 루프와 관련된 내용이군요! 좋은 내용입니다 ㅎㅎ