[JS/JavaScript] 자바스크립트(js) 동작원리
들어가기 앞서
흔히 JS, 자바스크립트라고 불리는 것은
동기일까요? 비동기일까요?
자바스크립트는 인터프리터언어입니다.
즉, 한줄씩 읽어가며 실행하는 프로그램이라고 생각하시면됩니다.
비동기라고 생각되시는 분들은 위에 2줄을 천천히 다시 읽어봐주세요
그럼에도
"비동기도 되는데?"
라고 생각 되시는분들은 아래글에서 같이 확인해보시죠!
가장 많이 사용하는 하나의 예제를 사용하도록 하겠습니다.
function A(){
B()
printf("A 출력")
}
function B(){
C()
printf("B 출력")
}
function C(){
printf("C 출력")
}
A();
위 코드를 실행하면 다음과 같은 출력이 나타납니다.
C 출력
B 출력
A 출력
분명 함수는 반대로 작성되어있는데 실행은 그 반대로 작동이 됩니다.
함수가 3개라서 헷갈린다구요? 좀더 심플하게 바꿔보겠습니다.
이제 위코드는 잊어버리시고 아래 코드를 다시 기억해주세요.
console.log("A 출력")
setTimeout(function(){console.log("B 출력")},1000)
console.log("C 출력")
중간에 이상한게 껴있긴한데... A 출력, B 출력, C 출력
을 하는 코드입니다.
우리는 위에서 JS는 인터프리터 방식이라고 설명을 했죠?
그럼 맨위부터
A 출력
---1초 쉬고~
B 출력
C 출력
이될거 같지만 사실은 그렇지 않습니다.
우리가 작성한 js,html,css는 웹엔진으로 해석이 되어 명령을 실행합니다.
그럼 웹엔진 내부를 알아야겠죠? 이게 js의 핵심입니다.
브라우저라고 불리우는 웹. 크롬,익스플로워,사파리...등 조금씩은 다르나 다 비슷하게 동작합니다.
그럼 본격적으로 어떤게 있는지 들여다보죠.
Memory Heap
Call Stack
WebAPIs
Callback Queue
Event Loop
크게 이렇게 나뉘어져 있습니다.
뭐가 뭔지..헷갈리니 저희는 간단하게 명을 바꿔보겠습니다.
Memory Heap => Heap
Call Stack => Stack
WebAPIs => 비동기 대기실
Callback Queue => Queue
Event Loop => Event
위에서부터 하나씩 예를 들어가며 간단 설명을 하겠습니다.
아래와 같은 코드가 있다고 가정해봅시다.
name = "홍길동"
age = "17"
console.log(name)
위 코드로 일부 설명을 하고, 기존에 작성한 코드로 마저 설명을 이어가도록 하겠습니다.
/**Heap 영역**/
name="홍길동"
age="17"
Heap은 메모리 할당이 일어나는 곳으로 객체가 담깁니다. 즉, 변수나 함수가 담긴다고 생각하시면 편해요.
/**Stack**/
console.log(name)
Stack은 실행할 코드 한줄이 들어가는 영역이라고 생각하시면 됩니다.
나머지는 위에 설명하던 코드로 마저 설명을 하겠습니다.
자, 그럼 다시 본론으로 들어와서 잊어버리셨겠지만 아래 코드를 다시 기억해주세요.
console.log("A 출력")
setTimeout(function(){console.log("B 출력")},1000)
console.log("C 출력")
그럼 우리가 실행하고자 하는 위코드는 어떤 영역에 있을까요?
"Stack", 정확히는 Call Stack입니다.
JS는 어떤방식의 언어이다? "인터프리터"
그럼 Stack에 있는 코드 한줄한줄을 읽게 되겠죠.
A 출력
그다음은?
C 출력
입니다. 왜 B 출력이 아닌가요?!
여기서 위에 적었던 개념이 등장합니다.
위로 올려서 보실 필요없이 다시 확인해 봅시다.
Memory Heap => Heap
Call Stack => Stack
WebAPIs => 비동기 대기실
Callback Queue => Queue
Event Loop => Event
일단..우리가 사용한 코드에서 Heap은 안봐도 될거같고..Stack은 방금 3줄의 코드가 보관되어있고..
나머지 3개중 적어도 1개가 관련있겠죠?
setTimeout인 경우 딜레이가 발생되는 함수입니다. 즉, 엔진입장에서는 기다림이 필요한 녀석인거죠.
그래서 js입장에서는
"야..나 할일 많아.. 너 잠시 저기 가있어봐"
라면서 setTimeout를 대기실로 보냅니다.
그리고 나머지 출력문이었던
C 출력
가 나오는거죠.
그럼 대기실에 있던 setTimeout은 시간이 지난후, queue로 보내지게 됩니다.
이부분이 아까 언급한 "브라우저라고 불리우는 웹. 크롬,익스플로워,사파리...등 조금씩은 다르나 다 비슷하게 동작합니다."의 차이점입니다.
우리는 setTimeout에 1000, 즉1 초를 부여했는데, 1초가 끝난뒤 queue로 갔을수도, 아니면 1초가 끝나기전에 queue로 이동했을수도 있어요. 브라우저마다 동작원리는 다르겠지만, 코드를 처리하는 stack입장에서는 상관할일이 아니죠.
다시 돌아와서 queue로 오게된 setTimeout는 event에 의해 stack에 가게됩니다.
그럼 간단하게 글로 재 설명을 해드릴께요.
stack에 "A 출력"이 들어가고, 나오면서 "A 출력"이 찍힙니다.
그다음 setTimeout가 들어가고, setTimeout는 특정 이벤트이기 때문에 WebAPIs로 옮겨 지게 됩니다.
그다음 "C 출력"이 들어가고, 나오면서 "C 출력"이 찍힙니다.
WebAPIs에 있던 setTimeout는 CallBack Queue로 이동하게 되고, Stack에 처리할 코드가 없다면 CallBack Queue에있는
setTimeout가 Event Loop에 의해 Call Stack으로 가게 됩니다.
왜 A다음 B가 아닌 C가 오는지 알게되셨나요?
그럼 다시 한번 질문드리겠습니다.
js는 동기적입니까? 비동기적입니까?
동기적이긴하나 가끔 비동기적인 처리도 가능하다. 입니다.
우리가 알고있어야하는 부분은 "처리도"가능한거지 비동기는 아닌거죠.
비동기적처리는 다양하지만 우리가 알고있는 것을 예로들면
1. 이벤트 리스너
2. setTimeout
3. Ajax
등 이있습니다.