자바스크립트는 싱글 스레드인데 비동기처럼 보이는 현상은 왜 그러는 걸까?
그건 자바스크립트 혼자서 일하는 게 아니라, 옆에 알바생을 하나 더 두기 때문이다.
바로 브라우저가 가지고 있는 Web API다.
자바스크립트는 할 일들의 리스트를 만들어 놓는다.
이 작업 리스트를 스택이라고 한다.
자바스크립트에서 무언가 실행되려면 무조건 이 스택 위에 올라가야 한다.
스택에서 무언가 실행할 때, 브라우저의 Web API로 헐 일을 넘겨 버리는 경우가 있다.
예를 들어 setTimeOut 함수나 Ajax 등이 그렇다.
이런 함수는 자바스크립트 스택에서 실행되지 않는다.
스택에서 하는 일은 web API로 넘기는 것까지다.
스택이 web api로 넘기고 나면, 자기 할 일은 끝난다.
이게 완료가 됐든 안 됐든 스택에서 지워 버린다.
나머지는 web api한테 맡겼으니까,
다시 말해 알바생한테 넘겼으니까,
거기서 알아서 할 일이다.
그러고 나면 할 일 다 했다고 생각하고 다음 스택으로 넘어간다.
web api는 넘겨 받은 함수를 독립적으로 수행한다.
근데 아까 무언가 실행되려면 무조건 스택에 올라가야만 한다며?
그런데 web api가 독립적으로 함수를 수행한다니?
web api에서 아무리 실행되어 봐야,
자바스크립트의 작업 스택에 올라가지 않으면 무용지물이다.
web api에서 실행이 끝나고 나면, 그 결과값이든 콜백 함수든, 어쨌든 결국은 스택에 올려야 한다.
알바생이 말한다.
저... 아까 맡기신 일 끝났는데요. 어떻게 할까요?
사장이 말한다.
기다려 봐. 지금 하는 일 마저 하고 봐 줄게.
알바생은 기다린다.
web api는 스택이 던져 준 함수를 실행한다.
실행이 끝나고 그 결과값이나 콜백 함수를 얻었더라도,
스스로 뭘 하지는 못하고 그냥 기다린다.
어디서 기다리는가?
task queue 태스크 큐다.
큐에 들어가서 쌓인다.
기다린다.
언제까지?
스택이 하던 일을 마저 하고, 비어 있는 상태가 될 때까지.
스택이 비는 상태가 되면, 큐에서 가장 오래 기다렸던 녀석 하나를 꺼내 온다.
스택에 올려 놓는다.
그리고 결과값이든 콜백 함수든 작업을 수행한다.
사장님이 알바생에게 일을 마구 던져 놓는다.
사장님은 자기 할 일 하러 나간다.
알바생은 사장님이 맡겨 놓은 일을 하나씩 처리한다.
처리가 끝난 일은 보고서를 만들어 놓고 다음 일을 처리한다.
보고서가 계속 쌓인다.
사장님은 자기가 할 일이 다 끝나고 나면 알바생에게 맡겼던 일을 보러 온다.
쌓여 있는 결재 서류를 보고 하나씩 처리한다.
알바생이 할 수 있는 일은 결과 보고서를 만들어 놓고 기다리는 것뿐이다.
그 결과를 가지고 어떻게 처리할지는 사장님이 직접 해야 한다.
여기서 event loop 이벤트 루프 라는 녀석이 까메오로 출연한다.
어떤 복잡한 프로세스를 하는 녀석은 아니다.
그냥 감시 요원 같은 녀석이다.
무엇을 감시하는가?
스택이 비어 있는지 감시한다.
아까, 큐는 스택이 비어 있는 상태가 될 때까지 기다린다고 했다.
스택이 빈 상태인지를 확인하고, 만약 비어 있다면 큐에서 작업 하나를 꺼내 스택에 올려 놓는다고 했다.
그 일을 하는 녀석이 바로 이벤트 루프다.
사장님이 손이 비었는지, 손이 비었다면 알바생이 쌓아 놓은 결과 보고서 하나를 들고 오고,
사장님이 아직 일하는 중이라면 알바생에게 잠시만 기다리라고 양해를 구한다.
그런 정도 역할이다.
스택이 비어 있는지 들여다 보고 있다가, 비는 상태가 되면 큐에서 가장 오래된 녀석 하나를 불러 오는 정도.
이제 비밀이 풀렸다.
자바스크립트는 싱글 스레드인가?
그렇다.
자바스크립트는 멀티 스레드처럼 일하는가?
그렇다.
왜?
자바스크립트는 혼자 일하지 않고, 사실은 web api랑 함께 일하기 때문에.
마치 옆에 알바생을 두는 것처럼.
단, web api가 끝낸 일은 스택보다 우선순위가 낮다.
스택이 하던 일을 멈춰 세울 수가 없다.
스택이 모든 일을 끝낼 때까지 옆에 서서 얌전히 기다린다.
그래서 알바생이라는 표현을 썼다.
알바생은 자기 할 일 다했다고 사장님을 멈춰 세울 수 없다.
사장님이 일을 끝마치면, 그때서야 알바생이 끝내 놓은 일을 들여다 본다.
스택은 자기 하던 일을 모두 끝마치고 비어 있는 상태가 되고 나서야 태스크 큐를 들여다 본다.
그 결과를 가져다가, 원래 하려던 일을 이어서 한다.
사장님이 자기 일을 하는 동안, 알바생도 여러 일을 끝마쳐 놓을 수도 있다.
알바생은 자신이 끝마친 일을 어딘가에 쌓아둔다.
그렇게 쌓아두는 곳이 task queue 태스크 큐다.
web api는 하던 일을 마치면 그 결과값이나 콜백 함수를 태스크 큐에 차곡차곡 쌓아 두고 나서 다시 자기 나름대로 할 일을 계속 한다.
사장님은 자신이 하던 모든 일을 끝마치고 나면 그때서야 알바생이 끝내 놓았던 일을 확인한다.
스택이 모든 일을 끝마쳤는지, 언제 태스크 큐에서 일을 꺼내 와야 하는지,
계속 감시하고 서 있는 게 이벤트 루프가 하는 일이다.
스택이 할 일이 없고 손이 놀게 되면 태스크 큐에서 일을 꺼내 온다.
이것이 자바스크립트가 멀티 스레드처럼 작동하는 전체적인 얼개, 매커니즘이다.
'JavaScript' 카테고리의 다른 글
select 태그에서 option 선택 값 바뀔 때마다 이벤트 걸기 (on change) (0) | 2022.04.02 |
---|---|
JavaScript 이벤트 객체란? 구조와 내용, 속성 값 꺼내 오기 (0) | 2022.04.02 |
나중에 추가한 자식 요소에 이벤트 추가하기 (delegated event) (0) | 2022.04.02 |
여러 계층에 걸쳐서 자식 요소를 선택하는 방법 jQuery 선택자 (0) | 2022.04.02 |
[JavaScript] var / let / const 차이점 비교 (스코프, 호이스팅, 선언) (0) | 2022.03.19 |