javascript 기초 이론 다지기

이장훈·2022년 2월 13일
0

자바스크립트와 Event Loop

Node를 잘 이해하기 위해서 자바스크립트의 동시성 모델/실행을 이해해야한다.

자바스크립트의 실행 모델은 event loop, call stack, call back queue

이벤트 루프 모델은 여러 스레드를 사용함.
그 중 우리가 작성한 자바스크립트 코드가 실행되는 스레드를 메인 스레드라 부릅니다.
한 node.js 프로세스에서 메인 스레드는 하나이며, 한 순간에 한 줄씩만 실행됨.
그 외의 일 (file I/O, network)를 하는 워커 스레드는 여럿이 있을 수 있다.

1.2 Call stack

  • 자료구조로, 지금 시점까지 불린 함수들의 스텍이다.
    함수가 호출될 때 쌓이고, 리턴될 때 빠진다.
  • stack은 쌓인 순서와 반대로 맨 마지막 부터 나간다.

실행 특성 run-to-completion

빈 상태에서 callback이 실행된다.
이 callback은 함수들이 계속 불려 call stack으로 쌓인다.
모두 쌓이면 이 상태에서 하나씩 빠지기 시작한다.
따라서 지금 처리하는 callback의 실행이 전부 끝나는 call stack이 완전 끝난 상태에서 다음 call back을 처리한다.

1.3 callback Queue

  • callback들이 쌓이는 Queue이다.
  • queue는 쌓인 순서대로 나가게 된다.
  • 콜백 큐(메세지 큐)는 앞으로 실행할 콜백(함수와 그 인자)들을 쌓아두는 큐이다.
  • 콜백은 브라우저나 Node가 어떤 일이 발생하면(event) 메인 스레드에 이를 알려주기 위해 (callback)을 사용한다.
  • 각각들어가는 handler 이벤트는 파일 처리의 완료, 네트워크 작업의 완료, 타이머 호출 등 다양하게 발생한다.
  • Call stack이 빈 상태까지 기다렸다가 callback queue에서 이벤트를 하나씩 꺼내 실행한다.

1.4

console.log('1')

setTimeout(() => {
console.log('2')
}, 0)

console.log('3')

while loop가 도는 동안 call stack이 절대 비지 않는다.
이 동안은 callback queue에서 콜백을 꺼낼 수 없으므로, setInterval이 아무리 콜백을 쌓아도 메인스레드에서 실행될 수 없다.
이런 경우 event loop를 block한다고 한다.

1.5 non-blocking I/O & offloading

node api를 통해 node에게 파일을 읽으라고 work thread에서 실행하게 하고, 다음 줄의 someTask를 실행한다.

브라우저나 node.js에서나, webAPI 혹은 Node API의 동작이 끝나면 callback queue에 등록합니다. 브라우저나 Node가 요청 받은 일을 하고 있는 동안 메인 스레드와 이벤트 루프는 영향을 받지 않고 계속 실행됩니다.
이를 offloading이라고 하며, Node 서버의 메인 스레드가 하나임에도 불구하고 빠르게 동작할 수 있습니다. 메인 스레드가 오래 걸리는 일을 기다리지 않기 때문입니다.

1.6 Event loop


1. callback queue에서 콜백을 꺼내고 (없다면 생길때까지 기다리고)
2. 그 콜백의 처리가 끝날때 까지 실행하고
3. 이를 반복한다.

1.7 Hoisting - var

  • var 키워드는 변수를 선언하는데, 그 선언이 같은 scope의 맨 위로 hoisting된다. 즉, 변수의 선언을 해당 scope의 위로 올립니다.

var x = 1
console.log(x) // 1

console.log(x) // undefined
var x = 1
즉 해석하면
var x
console.log(x)
x = 1 과 동일하여 변수 선언만 맨위로 hoisting되고, 초기화는 되지 않는다.

console.log(x)
x = 1
var도 없다면 변수의 선언 자체가 이뤄지지 않아 referenceError가 발생한다.

function foo() {
return 'foo'
}
console.log(foo())

console.log(foo())
function foo() {
return 'foo'
}
위 두 코드의 실행은 동일하다, function도 hoisting의 대상이기 때문이다.

profile
개발자가 꿈입니다.

0개의 댓글