동기 처리와 비동기 처리
•
JS엔진은 하나의 실행 컨텍스트(콜 스택) 스택을 갖기 때문에 2개 이상의 함수를 동시에 실행할 수 없다. --> 싱글 스레드
•
이 싱글 스레드는 한 번에 하나의 태스크만 실행할 수 있기 때문에 처리에 시간이 걸리는 태스크를 실행하는 경우 블로킹이 발생
const sleep = (func, delay) => {
const delayUntil = Date.now() + delay;
while (Date.now() < delayUntil);
func();
};
const foo = () => {
console.log('foo');
};
const bar = () => {
console.log('bar');
};
sleep(foo, 3000);
bar();
TypeScript
복사
타이머 함수가 아닌 일반 함수 작성된 몇초 후에 실행하는 함수는 동기 처리 방식으로 실행되어 foo가 콘솔에 출력되고나서 bar가 출력됨
•
setTimeout함수의 경우 태스크를 블로킹 하지 않고 곧바로 실행됨 --> 비동기 처리
•
비동기 처리의 단점
◦
콜백 헬을 발생시켜 가독성 저하
◦
비동기 처리 중 발생하 에러의 예외처리 곤란
◦
여러 개의 비동기 처리를 한 번에 처리하는 데 한계
•
타이머 함수인 setTimeout과 setInterval, HTTP 요청, 이벤트 핸들러는 비동기 처리 방식으로 동작
이벤트 루프와테스크 큐
•
자바스크립트의 동시성을 지원하는 것 --> 이벤트 루프
•
JS 엔진의 2가지 영역
◦
콜 스택: 실행 컨텍스트 스택
최상위 실행 컨텍스트가 종료되어 콜 스택에서 제거되기 전까지 다른 어떤 태스크 실행 X
◦
힙: 객체가 저장되는 메모리 공간
객체는 크기가 정해져 있지 않아서 메모리 공간의 크기를 런타임에 결정하며 구조화 되어있지 않다는 특징 보유
•
비동기 처리의 코드 평가와 실행을 제외한 모든 처리는 JS엔진을 구동하는 환경인 브라우저 또는 Node.js가 담당(호출 스케줄링을 위한 타이머 설정 및 콜백 함수 등록 --> 브라우저 또는 Node.js가 담당)
◦
태스크 큐: setTimeout이나 setInterval과 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역
◦
이벤트 루프: 콜 스택에 현재 실행중인 실행컨텍스트가 존재하는 지 확인하고, 콜스택이 비어있고 태스크 큐에 대기 중인 함수가 존재 시, 순차적으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동
•
setTimeout의 delay가 0인 경우, 지연시간이 4ms 이하이므로 최소 지연 시간 4ms가 지정이 되어 4ms 후에 콜백 함수가 태스크 큐에 푸시되어 대기
비동기 함수인 setTimeout의 콜백 함수는 태스크 큐에 푸시되어 대기 후, 콜 스택이 비게되면 그때 콜스택에 들어가 실행됨.(브라우저가 타이머 만료되면 콜백 함수를 태스크 큐에 등록해줌)
JS엔진은 싱글스레드로, 브라우저는 멀티 스레드로 동작.