본문 바로가기
JavaSciprt

[자바스크립트] 동기 , 비동기 그리고 태스크 큐, 마이크로 태스크 큐

by 리슨업 2024. 3. 2.

 

 

동기 ,  태스크 큐, 마이크로 태스크 큐

 


 

 

 

JavaSciprt는 하나의 싱글쓰레드를 사용하며, 스택에서 모든 이벤트를 처리하고 기본적으로
"동기"적으로 한번에 하나의 작업만을 수행할 수 있는 언어이다. 

 

자바스크립트의 모든 이벤트는 콜 스택에서 처리하게 되고 스택은 LIFO의 형태로 나중에 들어온 이벤트를 우선 적으로 처리한다. 

 

 

#스택 실행컨텍스트

const bar = () =>{
	console.log('bar');
}

const foo = () =>{
	bar();
    console.log('foo');
}
foo()

 

실행 순서는 

1. foo()를 실행하며 콜 스택에 배치  

스택
순서 foo()      

 

2, foo함수 내부의 지역스코프상 동지거 우선권인 bar()를 콜 스택에 배치

스택
순서 foo()  bar()    

 

3, bar() 함수내 console.log가 실행된 이후 실행될 이벤트가 없기에  bar()는 스택에서 제거

스택
순서 foo()       

 

4. 이후 foo() 함수내 console.log가 실행된 이후 foo()또한 스택에서 제거

스택
순서 CLEAR!

 

LIFO으로 실행함에 있어 인터프리터 언어의 동기적 특성을 명확하게 확인 할 수 있다.

 

#비동기와 태스트 큐

자바스크립트의 대표적인 특징으로 비동기를 다루는 별도의 쓰레드가 존재한다. 

비동기 함수는 대표적으로 setTImeOut을 예제로 많이두는데 

setTimeout(()=>{
	console.log(1);
},1000)

 

setTimeout 함수는 스택이 아닌 태스크 큐에 반영이 되며, 태스트 큐는 스택이 비어있는걸 확인 한 이후에 해당 작업을 콜스택에서 처리하도록 배치한다. 

위 코드의 컨텍스트는 1초뒤에 태스크 큐에 반영이되고 콜스택이 비어있음으로 콘솔에 "1"을 출력하는 이벤트 루프이다.

이벤트 루프는 콜 스택이 비어 있을 때 태스크 큐에서 작업을 가져와 콜 스택으로 옮기는 역할을 하는 자바스크립트의 특징 루프

 

비동기 함수는 동기함수 보다 랜더링에 우선순위가 밀리며 동기처리가 완료 된 이후에 처리된다라는 것을 기억하면된다.

또 다른점은 스택의 LIFO의 방식과 달리 태스트 큐는 FIFO(first in first out)로 먼저들어온 순서대로 처리한다.

 

 

 

#마이크로 태스트 큐

비동기 함수 통신에서 빠질 수 없는 대표적인 요소 중  "Promise"는 비동기 함수 이지만 태스트 큐가 아닌 마이크로 태스크 큐에 배치된다. 

마이크로 테스트 큐는 테스트 큐 보다 먼저 우선적으로 랜더링 되며, 동기 함수 이후 랜더링 된다. 

 

const test = () =>{
        const bar = () =>{
            console.log('bar');
        }
        setTimeout(()=>{
            console.log('테스크');
        },0);
        Promise.resolve().then(bar);
        console.log('동기');
}
test();

 

조금 불필요하게 짠 코드지만 나름 참고하기엔 나쁘지 않은 코드 같아서 짜봤다..

 

위 코드의 실행 컨텍스트 순서

1. test()를 호출하면 bar는 최상에 위치에 있지만 호출하지 않기에 콜 스택에 호출하지 않는다.

2. setTimeout은 0ms 초뒤 태스크 큐에 배치

3. Primise를 이용하여 bar를 마이크로 태스크 큐 배치시킨다. 마이크로 테스크 큐는 setTimeOut보다 우선 순위를 갖게 된다. 

4. console.log 는 동기 코드로 해당 스코프에서 가장 우선 순위를 갖게되며 제일 먼저 실행된다.

5. 최종 결과값은 가 되게 된다.

'동기'
'bar'
'테스크'

 

 

 

근데 보통 primise는 패칭이후 해당 데이터를 다루는 로직을 만들때 거의 많이 사용하기 때문에 보통은 async await로

콜스택을 비워두는 상태로 해당 함수가 처리하는 것을 await 하고 Primise를 반환하면 재개하는 방식으로 "동기적인 척"으로 많이 사용하기에 마이크로 태스크 큐만을 단독으로 사용하는 경우는 많이 없을 것 같다.

'JavaSciprt' 카테고리의 다른 글

[자바스크립트] 일급객체  (0) 2024.01.15
[자바스크립트] 클로저 , [[Enviroment]]  (0) 2024.01.13
[자바스크립트] - Scope  (1) 2023.12.28