함수를 호출하면 함수 코드가 평가 되어 함수 실행 컨텍스트가 생성됨
→ 이때 생성된 함수 실행 컨텍스트는 실행 컨텍스트 스택(콜 스택)에 푸시되고 함수 코드가 실행 됨
→ 함수 코드의 실행이 종료하면 함수 실행 컨텍스트는 실행 컨텍스트 스택에서 팝 되어 제거됨
eg.
const foo = () => {};
const bar = () => {};
foo();
bar();
⇒ 함수의 실행 순서는 실행 컨텍스트 스택으로 관리
자바스크립트 엔진은 단 하나의 실행 컨텍스트를 가지기 때문에, 한 번에 하나의 태스크만 실행 가능 (싱글 스레드 방식)
⇒ 때문에 처리에 시간이 필요한 태스크를 실행하는 경우 **블로킹(작업 중단)**이 발생
eg.
// sleep 함수는 일정 시간(delay)이 경과한 이후에 콜백 함수(func)를 호출한다.
function sleep(func, delay) {
// Date.now()는 현재 시간을 숫자(ms)로 반환한다.("30.2.1. Date.now" 참고)
const delayUntil = Date.now() + delay;
// 현재 시간(Date.now())에 delay를 더한 delayUntil이 현재 시간보다 작으면 계속 반복한다.
while (Date.now() < delayUntil);
// 일정 시간(delay)이 경과한 이후에 콜백 함수(func)를 호출한다.
func();
}
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
// sleep 함수는 3초 이상 실행된다..
sleep(foo, 3 * 1000);
**// bar 함수는 sleep 함수의 실행이 종료된 이후에 호출되므로 3초 이상 블로킹된다.**
bar();
// (3초 경과 후) foo 호출 -> bar 호출
bar
함수는 sleep
함수의 실행이 종료된 이후에 호출되므로 3초 이상 블로킹됨
⇒ 동기(synchronous) 처리: 현재 실행 중인 태스크가 종료할 때까지 다음에 실행될 태스크가 대기하는 방식
eg. 타이머 함수인 setTimeout
을 사용하여 수정한 버전
function foo() {
console.log('foo');
}
function bar() {
console.log('bar');
}
// 타이머 함수 setTimeout은 일정 시간이 경과한 이후에 콜백 함수 foo를 호출한다.
**// 타이머 함수 setTimeout은 bar 함수를 블로킹하지 않는다.
setTimeout(foo, 3 * 1000);**
**bar();
// bar 호출 -> (3초 경과 후) foo 호출**
타이머 함수 setTimeout
은 그 이후의 bar
함수를 블로킹하지 않고 곧바로 실행함
⇒ 비동기(asynchronous) 처리: 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하는 방식
장점) 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하므로 블로킹이 발생하지 않음
단점) 태스크의 실행 순서가 보장되지 않음
비동기 처리를 수행하는 비동기 함수는 전통적으로 콜백 패턴을 사용함 but..
비동기 처리 방식의 예시:
setTimeout
, setInterval
, HTTP 요청, 이벤트 핸들러
⇒ 이벤트 루프(event loop): 브라우저에 내장되어 있는 기능 중 하나로, 자바스크립트의 동시성을 지원함