코드를 잘 짜기 위해서는 동작 원리를 이해하는 것이 필요하다.
브라우저의 동작원리를 잘 알아야하는 이유라고 한다면, 자바스크립트를 실행시켜주는 녀석이 브라우저이기 때문이다.
일반적인 프로그래밍 언어들은 뒤에서부터 한 줄로 내려오면서 코드를 읽게 된다.
만약 콘솔 사이에 1초의 시간을 두고 싶다고 했을 때, 아래와 같이 작성하면
console.log(1+1)
setTimeout(function(){},1000)
console.log(2+2)
브라우서 상에서 1초를 쉬고 콘솔을 출력하지 않는다.
아래와 같이 작성해야, 비로소 1초 뒤에 콘솔이 출력된다.
console.log(1+1)
setTimeout(function(){
console.log(2+2)
},1000)
또 다른 예시로,
console.log(1+1)
setTimeout(function(){console.log(2+2)},1000)
console.log(3+3)
이렇게 작성할 경우, 2와 6이 먼저 출력되고, 4가 나중에 출력된다. 이와 같이 자바스크립트는 빨리 처리되는 순서대로 실행된다.
이게 왜 이렇게 되는지 이해하기 위해서는 브라우저의 동작원리를 이해할 필요가 있다.
웹브라우저는, 자바스크립트의 엔진을 실행시켜주는 녀석들이다. 그러니까 이 녀석들은 자바스크립트 코드를 해석하고, 그것을 실행하는 것이다. 자바스크립트의 내부를 들여다보자.
Stack과 Heap :
먼저 Stack이라는 공간이 있다. 이 안에는 우리가 실행하기 원하는 함수들이 저장되어 있다. 그리고 이 함수 안에 변수가 있을 경우에 이 변수가 어디에 있는지 찾게되는데, 그 변수들이 저장된 장소는 바로 Heap이라는 공간이다.
stack의 특징이 있다면, 하나밖에 없다. 그리고 위에서부터 아래로 하나씩 꺼내서 사용하는 구조이기 때문에, 한번에 하나의 코드밖에 실행할 수 없다. 그런 이유로 자바스크립트를 single threaded언어라고 부른다. 한번에 하나의 코드밖에 실행할 수 없다는 이야기다.
그런데 예를 들어서, setTimeout과 같은 함수들은 stack안에서 실행될 수가 없기 때문에, 잠깐 대기실에 들어가있다. 이렇게 대기실에 보내는 코드들은 정해져있다.
1)ajax요청 코드
2)이벤트리스너
3)setTimeout등등.
Queue :
이제 setTimeout에 설정해둔 시간이 되어서, 이 코드를 대기실에서 다시 stack으로 옮겨주어야 한다. 그래서 대기실에서 코드들을 Queue로 보낸다. 이 큐 안에서 대기가 끝난코드들이 하나씩 stack으로 옮겨진다.
이렇게 옮겨질 때, 조건이 있는데 stack이 비어있을 때만 올려보내진다. 스택이 비어있는 것을 확인하고, 큐에서 코드하나를 올리고, 스택이 비어있는 것을 확인하고 다른 코드하나를 올리고. 이런 방식으로 진행된다.
만약 setTimeout에 0초를 준다면? 순서대로 실행될까? :
그런데, 만약에 setTimeout에 0초를 주면 어떻게 될까? 논리적으로 봤을 때, 스택에 쌓여있는 순서대로 코드가 실행되는 것이 맞을 것 같다. 하지만 스택은 setTimeout이 0초이든 1초이든 무조건 대기실로 보낸다. 그래서 마찬가지로, 스택에 있는 코드가 비어있을 때에만 큐에서 다른 코드를 올려보낸다. 때문에 setTimeout의 경우에는 대기시간이 0초라고 할지라도 다른 코드들이 실행되고 나서 실행이 되는 것이다.
몇가지 교훈이 있다면,
1.stack을 바쁘게 하지 말자.(많은 시간을 소요하게 하지 말자)
2.queue를 바끄게 하지 말자.
해당 글은 아래 유튜브 강의를 듣고, 정리한 글입니다.
더 정확한 이해를 원하시면 아래의 영상을 시청하실 것을 추천드립니다! 짱 좋은 강의에요!
'Javascript' 카테고리의 다른 글
[자바스크립트] var, let, const 3가지 변수에 대한 정리 (0) | 2021.09.28 |
---|---|
[애플코딩] 자바스크립트 this란 무엇인가? (0) | 2021.09.22 |
[Javascript] 참조형과 원시형의 차이(reference vs primitive values) (0) | 2021.07.15 |
[javascript] 문서 위치 변경하는 법 (assign메서드) (0) | 2021.06.21 |
[javascript] 현재 요소의 URL,도메인명, 경로명, 프로토콜을 알아내는 법 (0) | 2021.06.21 |