비동기 처리
비동기 처리는 프로그램이 작업을 동시에 수행하는 것처럼 보이게 하는 처리 방법이다.
쉽게 말하면 일을 미뤄두고 다른 코드가 다 실행된 후 미뤄둔 일을 실행하는 처리 방식이다.
비동기 처리 과정
JS 코드가 실행될 때 비동기 함수를 만나면
비동기 함수에 등록된 코드는 event loop에 들어가고
해당 함수를 탈출해 나머지 코드를 실행한다.
이때 이벤트 루프는 queue 형태라고 생각하면 편하다.
기본적으로 선입 선출 구조이나 비동기처리 시 대기 시간을 정해두었다면
해당 대시 시간만큼만 event loop에 머물게 된다.
Event Loop
이벤트 루프는 아래의 그림과 같이 나타낼 수 있다.
여기서 중요한 개념은 stack과 queue이다.
call stack
위의 그림에 있는 stack은 흔히 call stack이라고 부른다.
call stack은 Javascript 코드의 실행을 추적하고 관리하는 메모리 구조로
함수 호출과 관련된 정보를 저장한다.
아래의 코드를 보면 이해가 쉽다.
참고로 stack은 선입 후출 구조이다.
function foo(b) {
const a = 10;
return a + b + 11;
}
function bar(x) {
const y = 3;
return foo(x * y);
}
const baz = bar(7); // 42를 baz에 할당
실행 과정
1. bar를 호출할 때 콜스택에 인수(7)와 지역 변수를 포함하는 첫 번째 프레임 push
2. bar가 foo를 호출할 때 foo의 인수(3*7)와 지역 변수를 포함하는 두 번째 프레임 생성 후 stack에 push
3. foo 반환 시 stack.pop 발생 ( 두 번째 프레임 stack에서 삭제 )
4. bar 반환 시 stack.pop 발생 ( 첫 번째 프레임 stack에서 삭제 )
이때 콜스택이 비게 되면 queue에 있는 작업들이 콜스택에 들어간다.
Microtask Queue & Macrotask Queue
비동기 처리 동작이 저장되어 있는 공간.
마이크로태스크 큐 (Microtask Queue)
Promise와 async 함수의 콜백이 여기에 들어간다.
이 큐의 작업들이 콜 스택이 비어있을 때 가장 먼저 처리된다.
매크로태스크 큐 (Macrotask Queue)
setTimeout, setInterval과 같은 타이머 함수의 콜백이 여기에 들어간다.
이 큐의 작업들은 마이크로태스크 큐의 작업이 모두 실행된 후에 순차적으로 처리된다.
즉 Promise와 async 콜백이 setTimeout, setInterval과 같은 타이머 함수보다 우선순위가 높은 것이다.
타이머 함수 대기시간이 0초일 때는?
// 1번
let num = 1;
// 2번
setTimeout(() => {
num = 2;
}, 2000);
// 3번
num = 3;
// 4번
console.log(num);
이 코드는 다음과 같이 동작한다.
실제로 초록색 블록과 파란색 블록 , 초록색 블록과 보라색 블록이 동시에 동작하는 것은 아니고
초록색의 블럭은 이벤트 루프 안에서 대기하고 있는 메시지를 표현한 것이다.
그러면 대기 시간이 0초라면 순서대로 실행되는 것이 아닐까??
// 1번
let num = 1;
// 2번
setTimeout(() => {
num = 2;
}, 0);
// 3번
num = 3;
// 4번
console.log(num);
실제로 위의 코드를 돌려보면 아래와 같이 동작한다.
대기시간이 0초이더라도 이벤트 루프의 매크로태스크 큐에서 기다리다가 다른 동기 작업들이 끝나면
마지막에 수행되기 때문에 똑같이 console에는 3이 찍힌다.
이와 같은 비동기 처리를 해주는 함수에는 setTimeout(), setInterval(), addEventListner 등이 있다.
결론
비동기 처리란 쉽게 말해 이벤트 루프에 처리할 코드를 넣어두고 나머지 동기 코드를 모두 처리한 후 하나씩 순서대로 이벤트 루프에서 꺼내서 코드를 실행하는 방식이다.
이때 이 이벤트 루프라는 곳에 담겨 대기하고 있다는 개념이 잘 잡혀 있어야 대기 시간에 따른 코드의 이해가 쉬울 것이다.
'자바스크립트' 카테고리의 다른 글
[TypeScript] 타입 스크립트 동작 원리 (0) | 2024.03.24 |
---|---|
[typeScript] React typescript 실행 과정 (0) | 2024.03.18 |
[Javascript] 이벤트 버블링 / 캡처링 / 위임 정리하기! (1) | 2024.01.28 |
[Javascript] HTTP / GET/ POST / PUT / DELETE / 총정리! (0) | 2024.01.28 |
[Javascript] Shallow copy Deep copy / 객체의 복사 (0) | 2024.01.21 |