• 동기(Synchronous) vs 비동기(Asynchronous)
일단 JavaScript는 동기식 언어(=단일 스레드)이다.
그렇다면 동기식, 비동기식이 뭔지 알아보자.
- 동기식
- 순차적으로 태스크를 수행
- 어떤 작업이 수행중이라면 뒤의 작업은 앞의 작업이 끝날때 까지 대기해야 함
- 블로킹이 발생
- 동시에 여러 작업 수행 X, 흐름 예측 쉬움
- 비동기식
- 병렬적으로 태스크를 수행
- 현재 작업의 종료 여부와 무관하게 다음 작업을 실행
- 동기 방식과는 달리 완료 순서가 보장되지 않음
- 블로킹이 발생하지 않음(non-blocking)
- 동시에 여러 작업 수행 O, 흐름 예측 어려움(무엇이 먼저 완료될 지 보장 X)
동기식.. 너무 비효율적인데?
그리고 브라우저는 여러 작업이 동시에 실행되지 않나?
-> 위의 의문에 대한 답변!
자바스크립트 자체는 동기방식이 맞음
하지만 대부분의 작업들이 비동기로 이루어지는 것
자바스크립트 런타임이 비동기 처리를 위한 Web API를 제공(setTimeout 같은..)
=> API 덕분에 비동기로 요청을 처리 가능한 것이였다..!
• 비동기 처리 방법
용어부터 알고 가자..!
- Memory Heap : 메모리 할당이 일어나는 곳
- Call Stack : 코드 실행에 따라 호출 스택이 쌓이는 곳
- Web API : 자바스크립트 런타임에서 지원해주는 API
- Event Loop : Call Stack에서 실행중인 컨텍스트가 있는지, Callback Queue에 대기중인 콜백함수가 있는지 계속해서 확인
- Callback Queue : 비동기 함수의 콜백함수/이벤트 핸들러가 일시적으로 대기하는 곳
∘ 호출 스택(Call Stack)
자바스크립트는 싱글 쓰레드 기반 언어 -> 호출 스택이 하나뿐
Call Stack은 정해진 사이즈가 존재하고, 하나씩 쌓이는 스택 구조여서 정해진 용량 초과 시 에러 발생
=> 이게 그 유명한 Stack Overflow!
이런 문제를 해결해주는게 EventLoop + Callback Queue
function foo() {
console.log("1");
}
function foo2() {
console.log("2");
}
foo();
setTimeout(function () {
console.log("3");
}, 2000);
foo2();
위 코드를 실행하면
1 -> 3 -> 2
가 출력될거라고 생각했지만
1 -> 2 -> 3
이 출력된다 .. 왜??
- foo()가 Call Stack에 쌓인 후, 1 출력 -> Call Stack에서 빠짐
- setTimeout()이 Call Stack으로 들어옴
- 비동기 함수 이므로 Web API에게 위임
- foo2()를 Call Stack으로 불러온 후, 2 출력 -> Call Stack에서 빠짐
- setTimeout()의 설정시간인 2초가 지나면, setTimeout()의 콜백 함수를 Callback Queue로 보냄
- EventLoop가 Call Stak이 비어있는지 확인
- 비어있으므로 EventLoop가 Callback Queue에 있는 콜백 함수를 Call Stack 으로 보낸 후 처리
- 3 출력 후 프로그램 종료
여기서 주의할 점은 setTimeout()이 foo2() 종료 후 실행되는 것 X
Web API로 넘어간 시점부터 처리되고 있는 것임!
'HTML,CSS,JS' 카테고리의 다른 글
JavaScript Hoisting(호이스팅) (0) | 2023.05.15 |
---|---|
[JS] JavaScript 비동기 처리 방법(Promise, async, await) (0) | 2023.05.03 |
JavaScript란? (0) | 2023.05.03 |
JavaScript 기본 문법 (0) | 2023.04.29 |
[HTML] 헷갈리는 태그들 (0) | 2023.04.16 |