상세 컨텐츠

본문 제목

[JS] 자바스크립트 실행 순서 (feat. 이벤트루프)

TIL (Today I Learned)

by NayC 2021. 12. 2. 16:48

본문

728x90

동기적으로 진행되는건 '호출 스택'으로 파악 가능

함수 선언 = 메모리에 올렸다는 것.
함수 호출 = 메모리에서 선언했는지 찾아보고 실행 (실행이 완료되면 stack에서 빠짐)
cf) Anonymous는 가상의 전역 컨텍스트 (항상 먼저 stack에 있다고 보면 됨. 빠질 때도 맨 마지막으로 빠지고)

cf)

function run(){ 
	console.log('3초 후 실행'); 
} 
console.log('시작'); 
setTimeout(run, 3000); 
console.log('끝');

이 경우를 호출 스택으로 분석할 경우

메모리 스택 콘솔창
run 올라가고 anonymous  
  console.log('시작') 올라갔다가 실행되고 나감 시작
  setTimeout 올라가서 실행되고 나감  
  console.log('끝') 올라갔다가 실행되고 나감
  anonymous 나감  

-> setTimeout이 실행되지 못함


비동기 코드는 '이벤트루프' 개념 필요

가운데 화살표가 이벤트 루프

 

메모리 스택 백그라운드
- 장점 : 스택 부분이랑 동시에 실행됨
- 주의 사항 : 백그라운드 함수가 먼저 끝나도, 스택에 있는 함수를 '먼저' 처리해줘야 함
태스크 큐 콘솔창
run 올라가고
- 선언한 것들 올려주는 거라 메모리는 꼭 그리지 않아도 됨
- 추후 scope 개념 더 보충 필요
anonymous      
  console.log('시작') 올라갔다가 실행되고 나감     시작
  1
setTimeout 올라가서 실행되고 나가는데...! '비동기 함수' 같은 경우엔 백그라운드로 감
2
setTimeout(run, 3000)
   
  console.log('끝') 올라갔다가 실행되고 나감    
  3
anonymous 나감-> 스택 부분이 비어지면 이제 백그라운드에 있는 함수가 태스크 큐로 감
  4
run (백그라운드에 있던 함수가 여기에 온 것. 백그라운드 함수는 지워지고 여기 오는 것)
 
  5
run (호출 스택 비어있으면, 태스크 큐는 스택으로 함수를 보냄. 이벤트 루프가 이 처리를 하는 것)

     
  6
run 안에 있던 console.log('3초 후 실행')이 다시 스택에 올라왔다가 나감
    3초 후 실행
  run 함수 지워짐      
  호출 스택, 백그라운드, 태스크큐가 다 비어져있으면 js가 다 실행된 것  



연습

function oneMore(){ console.log('one more'); } function run(){ console.log('run run'); setTimeout(() => { console.log('wow'); }, 0) new Promise((resolve) => { resolve('hi') }) .then(console.log); oneMore() } setTimeout(run, 5000);

 

메모리 스택 백그라운드 태스크 큐 콘솔창
oneMore, run anonymous      
  setTimeout(run, 5000) 실행되고 나감. 나가는데 백그라운드로 나감 2
setTimeout(run, 5000)
- 이제 이 아이는 5초를 센 다음에(!), 스택이 비어진 것까지 확인하면 태스크 큐로 감
   
  1
anonymous 나감
  3
run
- 스택이 비어져있으면 스택으로 이동
 
  4
run
     
  console.log('run run') 올라왔다가 실행되고 나감     run run
  setTimeout(익명함수, 0)
- 0초여도 setTimeout은 무조건! 백그라운드 거쳐야 함
setTimeout(익명함수, 0)    
  new Promise

실행되고 나감(2)
     
  resolve('hi')
- Promise는 자기 내부 영역은 '동기'임. 즉, Promise 실행되면서 내부 함수 같이 실행되서 같이 올라온 것

실행되고 나감(1)
     
    then console.log('hi')
- Promise는 .then을 만나는 순간 '비동기'가 됨
   
  oneMore()      
  console.log('one more')
- 위에 oneMore() 실행되며 올라온 것
    one more
  // 지금 백그라운드 외 다 비어진 상태. (회색 처리가 run 함수 부분)  
      익명 함수
- 백그라운드에 2개가 있던 상황인데, 먼저 끝나는걸 태스크 큐에 올려줌. 0초를 가지고 있던 익명 함수가 먼저 끝나기에 먼저 처리를 해주는 것
 
      console.log('hi')  
  console.log('hi') 실행되고 나감
- Promise가 '우선권'을 가진다. ("setTimeout아, 나는 Promise란다. 먼저 갈게")
    hi
  익명 함수 실행되고 나감     wow
  5초 뒤에 run run, one more, hi, wow 순서로 뜸  


* 우선권 가지는 것들 *
Promise.then/catch
process.nextTick

cf) js는 싱글스레드인데 백그라운드에서 동시 처리해줄 수 있는 이유
-> 이 부분은 js가 아니라 C++ 등 다른 언어로 만들어준거라서 가능

728x90
반응형

관련글 더보기