-
NodeJs 호출 스택,이벤트 루프개발언어/Node.js 2022. 12. 13. 10:03
1. 호출 스택
⭐️호출 스택은 Execution Context(실행 컨텍스트)와 밀접한 연관이 있다.
function first(){ second(); cosole.log('첫 번째'); } function second(){ third(); cosole.log('두 번째'); } function third(){ cosole.log('세 번째'); } first();
함수를 선언했다는 것은 해당 함수를 메모리에 올렸다는 것이다. 메모리는 임시 저장장치이다. 컴퓨터가 잠깐 기억하고 있다가 새로 고침하면 저장이 사라진다.
마지막에 first();로 first()함수를 호출하고, 메모리속에 해당 함수가 선언이 되었는지 찾아본다. 호출하는 것은 실제로 실행하는 것이다. first()함수는 첫 줄에서 바로 second()함수를 호출한다. 그리고 second()함수는 첫줄에서 third()메서드를 호출한다. 그럼 결국엔 third()메서드에 있는 console.log가 제일 처음으로 실행된다.
JavaScript의 실행순서를 머리로 그릴 수 있어야 한다.
위 코드의 순서 예측해보기
- 세 번째 -> 두 번째 ->첫번째
호출스택 그래프
함수들을 호출할 때 스택처럼 쌓인다고 해서 호출스택이라고 한다.
호출 스택 (함수의 호출, 자료구조의 스택)
- Anonymous은 가상의 전역 컨텍스트(항상 있다고 생각하는게 좋다)
- 함수 호출 순서대로 쌓이고, 역순으로 실행된다.
- 함수 실행이 완료되면 스택에서 빠진다.
- LIFO 구조라서 스택이라고 불린다.
*LIFO : 후입선출 또는 last in, first out 컴퓨터 과학과 대기 이론에서 어떠한 종류의 데이터 구조에 저장되어 있는 항목들이 처리되는 순서를 말한다.
*stack(스택) : 스택은 한쪽 끝에서만 자료를 넣거나 뺄 수 있는 선형 구조(LIFO)으로 되어있다.
함수를 하나 실행하는 중에 그 함수안에서 다른 함수가 실행되면, 호출 스택에 나중에 들어갔다. 먼저실행된다.즉 호출순서로 stack에 들어가고 호출 역순으로 stack에서 빠져나오면서 실행된다.
anonymous는 파일이 시작될때 생기고, 파일이 끝나면 사라진다. 그래서 마지막에 있는 anonymous까지 사라지면 JavaScript의 실행이 완료된다. anonymous는 전역 scope라고 생각해도 좋고 전역context라고 생각해도 좋다.
동기 코드의 호출스택
호출스택은 JavaScript가 어떻게 돌아가는지, 어떤 순서대로 실행되는지 파악할 때 중요한 것이다. 파일이 시작되면 호출스택에 anonymous라는 것이 제일 밑에 깔리고, 그 위에 함수가 쌓인다음 모든 함수의 실행이 완료되면 빠진다.
그런데 함수가 실행되는 와중에 다른 함수가 실행될 때 가 존재한다.
만약 그렇지 않은 경우
ex) first()함수에서 second()메서드가 실행되지 않고, first()함수가 끝난후에 실행이 될경우 first()함수가 호출스택에 들어가서 실행이 완료되어 호출스택 밖으로 나간뒤에 second()함수가 호출스택 속에 들어가는 것이다.
호출스택은 코드가 동기(블로킹)으로 실행되었을 때의 순서다. JavaScript가 동기적으로 어떻게 실행되는지 파악할 때 사용하는 것이 호출스택이다.
JavaScript 코드는 항상 위에서 아래로, 오른쪽에서 왼쪽으로 실행된다.
비동기 코드의 호출스택
function run(){ console.log('3초 후 실행'); } console.log('시작'); setTimeout(run,3000); console.log('끝');
위 코드 순서 예측해보기
- 시작->끝->3초 후 실행
- 호출 스택만으로 설명이 안된다.(run은 호출되 되지 않음)
- 호출스택 + 이벤트 루프로 설명이 가능
setTimeout()이 유명한 비동기 코드이다.
함수 run()이 일단 선언되면, 메모리 어딘가에 함수 run()이 저장이 될 것이다.
동기 호출스택으로만 설명하자고 하면, 메서드 run이 실행될 틈이 없다. 그래서 호출스택만으로는 JavaScript의 모든 동작을 설명할 수 없다. setTimeout()메서드는 비동기 코드이기때문이고, 비동기 코드를 설명하기 위해서는 Event Loop를 알아야한다.
이벤트 루프
setTimeout()같은 비동기 함수의 역할은 백그라운드에 타이머(run,3초) 와 같은 코드를 보내준다. 준다. 백그라운드에 장점은 코드가 백그라운드에 가면 동시에 실행된다. 호출스택과 백그라운드가 동시에 실행되기 때문에 호출스택에서 그 다음 동작인 console.log('끝')이 실행되는 와중에도 백그라운드에서 타이머는 3초를 계속 세고 있는다.
즉 백그라운드에 가면 동시에 시작이 가능하다.
console.log('끝')과 타이머(run,3초)를 비교해서 백그라운드에 있는 코드가 먼저 끝나더라도 항상 호출스택에 있는 코드가 먼저 처리가되어야 한다.
console.log('끝')이 실행되고나면 파일의 실행이 모두 끝나서 anonymous도 사라진다. 그럼 호출스택이 텅 비어 있게된다. 하지만 여기서 끝나지 않고, 백그라운드의 타이머(run,3초)가 3초가 지난 후 메서드 run()을 태스크 큐로 보내준다. 그때 Event Loop의 역할은 호출 스택이 비어 있을 때 태스크 큐에서 각 각 메서드를 순서대로 호출스택에 넣고 실행해 준다는 것이다.
Event Loop가 태스크 큐에 있는 매서드를 호출스택에 보내주고 , 호출스택은 메서드 run()을 실행해 준다. 호출스택, 백그라운드, 태스크 큐가 모두 비어있으면 JavaScript실행이 완료된 것이다.
백그라운드에 함수는 동시에 처리되니까 비동기이다. 또한 백그라운드의 함수는 다른 스레드에 의해서 실행되어 멀티쓰레드도 실행된는 것과 다름이 없다.
⭐️NodeJS에서는 백그라운드에 보낼 수 있는 함수를 제한해 두었다.
ex) setTimeout(), setinterval(),다른 서버로 갖다오는 네트워크 요청과 같은것, 하드디스크에 있는 파일을 읽는 fs같은 명령어, 암호와 하는 crypto라는 명령,압축하는 명령
정해진 명령이나 작업만 백그라운드로 보낼 수 있고, 나머지 대부분의 코드는 동기적으로 돌아간다.
'개발언어 > Node.js' 카테고리의 다른 글
NodeJS - const, let /템플릿 문자열, 객체 리터럴/ 화살표 함수 (0) 2023.02.18 NodeJS - Call Stack, Back Ground, Task Queue (0) 2023.02.17 NodeJs 블로킹과 논블로킹 I/O (0) 2022.12.12 NodeJs 서버로서의 노드 (0) 2022.12.12 NodeJS 스레드 (0) 2022.12.12