[JavaScript] 동기, 비동기 프로그래밍_2

은지·2024년 1월 19일
0

슥 삭 슥 삭

목록 보기
4/8
  1. 이벤트 루프
  2. 태스크 큐
  3. 잡 큐 / 마이크로 태스크 큐


자바스크립트 엔진은 비동기 처리를 제공하지 않기 때문에 비동기 코드를 처리하는 모듈이 자바스크립트 엔진 외부에 있다.

즉, 싱글 스레드로 동작하기 때문에 한 번에 하나의 태스크만 처리할 수 있다는 것이다.
그치만 자바스크립트는 동시성을 지원하는 이벤트 루프 가 브라우저에 내장되어 있어 비동기 처리를 구현해낼 수 있다.

메인 스레드의 콜 스택(Call stack - execution context stack) 은 비동기 환경인 태스크 큐(Task queue)잡 큐(Job queue) 로 부터 비동기 코드의 호출, 반환을 처리한다.

이 과정에서 모든 코드가 실행되어 콜스택이 비워지면 이벤트 루프를 체크하면서 태스크 큐에 태스크가 남아있는지 확인한 후 콜스택으로 가져와서 처리할 수 있다.
엘리스 코딩 자료

이 과정에서

1. 이벤트 루프

이벤트 루프는 콜 스택에 현재 실행중인 실행 컨텍스트가 있는지, 그리고 태스크 큐에 대기 중인 함수(콜백 함수, 이벤트 핸들러 등)가 있는지 반복해서 확인한다.

만약 콜 스택이 비어 있고 태스크 큐에 대기중인 함수가 있다면 이벤트 루프는 순차적으로 태스크 큐에 대기중인 함수를 콜 스택으로 이동시킨다.
(자바스크립트 엔진은 콜 스택이 비워지면, 태스크 큐의 콜백 함수를 실행한다.)

function greeting () {
	console.log('Hey');
}
function closing () {
	console.log('See you');
}
setTimeout(greeting, 0);
closing();

// 1. 실행 컨텍스트 생성, 콜 스택에 푸시
// 2. setTimeout 함수 호출 > 실행 > 콜 스택에서 pop > 태스크 큐에 push
// 3. 이벤트 루프에 의해 콜 스택이 비어있음을 확인 > 태스크 큐에 대기중인 greeting이 콜 스택에 push
// 4. 콘솔창 : See you
//           Hey

2. 태스크 큐

태스크 큐이벤트 큐( event queue ), 콜백 큐( callback queue) 로도 불리며 setTimeout, setInterval 과 같은 비동기 함수의 콜백 함수, 이벤트 핸들러가 일시적으로 보관되는 영역이다.


자바스크립트는 비동기 처리를 위한 패턴으로 Promise를 도입했다.
Promise API에서는 태스크 큐가 아닌 잡 큐, 마이크로 태스크 큐를 사용하는데 둘 다 태스크 큐 보다 우선순위가 높다.

setTimeout( () => {
	console.log("타임아웃 1")
}, 0);

Promise.resolve().then( () => console.log("프로미스 1"));

setTimeout( () => {
	console.log("타임아웃 2")
}, 0);

Promise.resolve().then( () => console.log("프로미스 2"));

// 실행결과 : 프로미스 1 > 프로미스 2 > 타임아웃 1 > 타임아웃 2

3. 잡 큐 / 마이크로태스크 큐

잡 큐( job queue )와 마이크로태스크 큐( microtask queue )는 비동기 API 중 하나인 Promise API에서 사용되며 마이크로태스크 큐 > 잡 큐 > 태스크 큐 순서로 우선순위를 가진다.

마이크로태스크 큐는 Promise의 콜백 함수들이 실행되는 장소로 then(), catch(), finally() 와 같은 메소드들이 호출되는 비동기 작업이 완료된 직후에 해당 작업의 콜백 함수가 등록된다.

또한, 마이크로태스크 큐는 현재 실행중인 태스크가 완료되면 즉시 실행되며 Promise.resolve(), Promise.reject() 로 생성된 promise에 해당하는 콜백을 등록할 수있다.


잡 큐는 주로 비동기 함수의 콜백 함수가 등록되는 곳으로 setTimeout 또는 setInterval과 같은 비동기 함수의 콜백 함수가 등록되고 처리된다.

console.log("start");

// Promise
Promise.resolve().then(() => console.log("micro 1"));
Promise.resolve().tehn(() => console.log("micro 2"));

// setTimeout
setTimeout(()=> console.log("job 1"), 0);
setTimeout(()=> console.log("job 2"), 0);

console.log("end");

// 출력결과
// start
// end
// micro 1
// micro 2
// job 1
// job 2


참고문헌 : 모던 자바스크립트 Deep Dive | 저자 : 이웅모 | 출판 : 위키북스

profile
두 줄 소개

0개의 댓글