티스토리 뷰
728x90
개발자로써 프로그래밍 언어에 대한 동작원리를 파악하는게 왜 중요할까??
- 좋은 코드를 잘 짜고 싶으면 문법외에도 동작원리에 대한 개념 이해가 반드시 필요하기 때문이다.
- 좋은 코드란? 가독성이 좋고 성능 향상 및 테스트 하기 좋은 코드를 의미한다.
브라우저에 대한 이해도가 필요한 이유???
- 자바스크립트로 작성한 코드를 브라우저가 실행시키기 때문이다.
- 브라우저는 자바스크립트를 실행해주는 엔진인 셈이다.
About Javascript 💁🏻♂️
- 자바스크립트는 한번에 코드 하나 밖에 실행하지 못하는 특징을 가지고 있다. 이를 싱글 쓰레드(Single Threaded)라고 부른다. 따라서 원래 병렬처리가 불가능한 언어이다.
- 더 쉽게 이해하자! alert창을 띄워놓으면 닫기 전까지 어떠한 동작도 하지 못한다는 것을 생각해보아라.
- 자바스크립트는 동기적으로 처리하는 언어이다. 하지만 setTimeout, 이벤트 리스너, ajax, Promise(then)를 통해서 비동기적 처리가 가능한 언어이다.
- 만약에 1분 이상 걸리는 작업이 있다면 어떻게 해야할까?
- 1분 동안 아무 작업도 하지 못하는데 이때 사용하는 것이 비동기 콜백이다!
- 콜백(Callback)이란?
- 예를 들어 라면을 끓인다고 가정해보자. 라면을 끓일 때 물 넣고, 라면 넣고, 계란 넣고, 파 넣고 이런식으로 순차적으로 진행하게 된다. 라면을 먼저 넣을지 스프를 먼저 넣을지는 사람의 기호에 따라 달라지게 되는데 자바스크립트 또한 함수 실행이 끝나면 다음 실행할 일을 정해야하는데 이 다음 작업을 정하는 것을 콜백(Callback)이라고 부른다.
setTimeout(function test() {console.log("hello")}, 2000)
- 다음과 같은 코드를 보면서 콜백 함수의 개념을 이해 해보자!
- setTimeout 함수에서 2초가 지난 후 hello가 출력이 되는 것을 알 수 있다. 이와 마찬가지로 함수가 정해놓은 일을 끝낸 후, 후속으로 하려하는 작업을 실행하는 함수가 콜백함수이다.
자바스크립트 엔진 구성 ⚙️
- 자바스크립트 엔진은 V8 엔진구조를 예시로 들었습니다.

- 자바스크립트 엔진은 크게 Memory Heap, Call Stack으로 구성되어 있다.
- Memory Heap은 선언한 변수나 함수, 객체들이 할당되는 곳이다.
- Call Stack은 작성된 코드를 쌓아두고 한줄 한줄씩 처리하는 곳으로 즉 실행될 코드의 한줄 단위로 처리하는 역할을 한다.
- Call Stack은 하나만 존재하기 때문에 한번에 하나의 코드만 처리할 수 밖에 없다.
- Call Stack에 시간이 오래걸리는 작업을 처리한다면? 뒤에 있는 특정 코드는 실행되지 못하며 웹 사이트가 동작이 되지 않는다. 이때 필요한 곳이 바로 web API & Callback Queue, event loop이다.
- Call Stack은 하나만 존재하기 때문에 한번에 하나의 코드만 처리할 수 밖에 없다.
- web API는 비동기 처리를 담당하는 대기실과 같은 곳이다.
- Call Stack에서는 비동기 작업을 처리하지 않고 web API로 보내는데 대표적인 예로는 Ajax requset, setTimeout, Promise, 이벤트 리스너 등이 있다.
- 자바스크립트의 싱글 쓰레드의 영향을 받지 않고 독립적으로 처리하는 특징이 있다.
- Callback Queue는 비동기 처리가 끝난 후 실행되어야 할 함수들이 차례대로 할당되는 곳이다.
- 더 쉽게 이해하자! 사람이 어떤 일을 끝나면 다른 할 일을 머리속에 저장해 놓고 일을 처리하는 것과 마찬가지로 브라우저 역시 Callback Queue에 저장하고 사용하는 방식이다.
- event loop는 Queue에 할당된 함수를 순서에 맞춰서 Call Stack에 할당해주는 역할을 하는 곳이다.
- event loop는 반드시 Call Stack이 비어있어야만 Queue에 있는 함수를 전달한다.
- evnet loop는 반복적으로 Call Stack이 비어있는지 확인하는데 이를 tick이라고 부른다.
예시 코드 🫥
console.log("시작");
setTimeout(function test(){console.log("중간");}, 2000)
console.log("끝");
예시 코드를 통해서 자바스크립트의 동작 원리에 대하여 쉽게 알아보자.

- 자바스크립트는 동기적으로 처리하는 언어이기 때문에 코드는 순서대로 실행된다. 따라서 첫 코드인 console.log("시작")이 실행되는 것이다. console.log("시작") 코드가 Call Stack에 처음으로 할당되게 되고 처리되게 된다.


- 다음으로 두 번째 코드인 setTimeout 함수가 Call Stack에 들어가게 되는데 setTimeout 함수는 비동기 함수이기 때문에 Call Stack에서 바로 실행되지 않고 web API로 콜백 함수 test()가 들어가게 된다.

- 아직 2초가 지나지 않았기 때문에 web API에 콜백 함수가 담겨 있고 그 다음 코드인 console.log("끝") 이 Call Stack에 들어가서 실행이 된다.

- 2초가 지난 후 test() 함수는 Callback Queue에 담기게 된다. 2초가 지나면 event loop가 Call Stack이 비어있는지를 확인하게 된다.


- event loop가 Call Stack이 비어있는지 확인하고 난 후 test() 함수를 Callback Queue로 부터 Call Stack으로 보내게 된다. 따라서 test() 함수 안에 있던 console.log("중간") 코드가 호출되고 실행되는 것이다.
코드 출력 결과 💻
시작 👉 끝 👉 중간
다른 예시 🫥
console.log("시작");
setTimeout(function test(){console.log("중간")}, 0);
Promise.resolve()
.then(function (){console.log("Promise")}
);
console.log("끝");
출력 결과는 어떠할까?
* then 보다 setTimeout 함수가 먼저 끝났다는 것을 가정하고 진행
- 콜 스택에 console.log("시작") 이 담기고 출력이 된다.
- setTimeout 함수가 web API에 담긴다.
- Promise가 콜 스택에 담긴다.
- promise는 비동기가 아니다. 동기이다!!!!!!
- 근데 왜 비동기적 처리일까? then을 만나는 순간 비동기로 동작하기 때문이다.
- Promise가 web API로 옮겨진다.
- console.log("끝") 코드가 콜 스택에 담기고 출력이 된다.
- web API로 부터 콜백 큐에 timeout, then이 순서대로 담긴다.
- 이벤트 루프는 항상 콜 스택이 비어있는지 검사중!
- 이때 콜백 큐에 담긴 timeout, then 어떠한 순서대로 처리할 것인가?
- 큐이기 때문에 선입선출(FIFO) 방식이다?
- 아니다! 우선순위에 의해서 then을 먼저 처리하게 된다.
- 큐이기 때문에 선입선출(FIFO) 방식이다?
- 따라서 then 구문이 먼저 실행되고 setTimeout 함수 순으로 실행이 된다.
코드 출력 결과 💻
시작 👉 끝 👉 Promise 👉 중간
promise가 왜 setTimeout보다 우선순위가 높을까?
이전 예시 코드에서 setTimeout이 promise보다 먼저 콜백 큐에 먼저 들어왔는데 왜 promise가 먼저 실행이 되었을까?
- 콜백 큐는 Microtask Queue(Job Queue), Task Queue(Event Queue), Animation Frames 이렇게 3가지로 구성되어 있다.
- 우선순위는 Microtask Queue > Animation Frames > Task Queue 이다.
- 즉 이벤트 루프는 콜백 큐에서 가장 먼저 탐색하는 큐가 마이크로 큐인 셈이다. Microtask Queue에 promise가 담기는 것을 의미하고 setTimeout은 테스크 큐에 담긴다. 그래서 promise가 setTimeout 함수보다 먼저 실행되는 것이다.
- 이것이 이벤트 루프의 동작방식이다.
번외 🐭
call stack size exceeded
- 웹 개발을 하다가 맞닥뜨릴 수 있는 에러이다.
- 콜 스택에서 코드가 하나씩 담기다가 한계점을 초과하는 에러이다. 콜스택마다 담길 수 있는 한계점이 존재하는데 브라우저 혹은 엔진마다 콜스택의 한계점이 다르다.
- 일반적으로 1만개 정도를 담을 수 있으며 크롬 같은 경우는 약 12만개 정도를 담을 수 있다.
결론 📌
자바스크립트는 오랜 시간이 걸리는 연산이나 작업을 실행시키면 안된다. (복잡한 for문이나 복잡한 연산을 수행하지마세요!)
why? 만약 10초가 걸리는 작업을 수행하는 동안 버튼 클릭이나 ajax 요청 후 실행하는 코드는 10초동안 실행이 되지 않기 때문이다. 이러한 이슈는 브라우저 프리징을 유발시킬 수 있기 때문이다.
스택과 큐를 바쁘게 만들지 말자! 이것 자체로도 웹사이트가 버벅될 수 있으며 사용자는 3초동안 동작하지 않는 웹 사이트를 기다리지 않는다.
728x90
'JavaScript' 카테고리의 다른 글
| List & Array (2) | 2022.09.13 |
|---|---|
| 자바스크립트 메모리 관리 (0) | 2022.08.02 |
| JavaScript - Event (0) | 2022.05.08 |
| JavaScript - style property & class control (0) | 2022.05.08 |
| JavaScript - DOM 접근하기 (0) | 2022.05.08 |
댓글
01-26 18:39
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
글 보관함
250x250