어떻게 비동기적으로 동작하는지?
Memory heap, call stack, web apis, callback queue, event loop에 대해서 알아보자
Javascript는 SingleThread이다.
하나의 스레드에서 작업을 처리하기 때문에 작업1이 끝날때까지는 작업2, 3을 할 수 없다. 예를들어 클릭을 하고 이벤트를 처리하는 과정에서는 load가 멈춰있다고 형태와 같다. 당연히 유저에게 불편함을 초래한다.
싱글스레드와 단짝으로 붙어다니는 용어가 논블로킹이다.
자바스크립트는 하나의 스레드에서 처리를 하기 때문에 블로킹을 하게 되면 작업 1이 끝나야지만 그 다음 작업이 실행된다. 동시에 작업 2, 작업 3등이 처리가 될 수 없게 된다.
논블로킹이란?
단순하게 블로킹을 하지 않는다는 의미로 볼 수는 있지만 Non-blocking은 작업이 완료될 때까지 기다리지 않고 다음 작업이 진행될 수 있도록 동작하는 패러다임이다. 반대로 블로킹은 동기적인 상황에서 다음 작업이 막힌 상태를 말한다. 자바스크립트가 싱글 스레드임에도 불구하고 비동기적 동작이 가능한 이유가 javascript 비동기 함수는 사실 비동기 + 논 블로킹 함수이기 때문이다.
JS엔진: JS파일을 사용 시 메모리 힙과 콜 스택을 사용해서 컴퓨터가 이해할 수 있는 기계어로 컴파일을 하고 실행할 수 있도록 한다.
Memory Heap: 선언한 변수들이 기록되는 장치
call stack: 저장해 둔 함수가 저장되고 실행될 수 있는 역할을 담당을 한다. 콜 스택은 말 그대로 call (call은 function을 의미) 이 stack처럼 쌓이는 Stack이다. 데이터 구조 중 하나로 어떠한 함수가 저장되고 실행되는 지 알 수 있고 하나씩 차례대로 콜이 쌓인다.
web APIs: JS엔진이 실행되는 환경은 OS, 브라우저, Node.js 등등 다양하다. 즉 web API는 브라우저에서 제공하는 api가 있다는 것으로 그 종류가 다양하고 많다. 대표적으로 DOM, AJAX, Timeout이 있다.
Callback Que :다른 함수에게 인자로 전달되는 자료구조의이다. onClick, onLoad, onDone등이 있고 콜스택과 다르게 가장 먼저 들어온 함수를 가장 먼저 처리한다.
Event Loop: 콜 스택이 다 비워지면 콜백 큐에 존재하는 함수를 이벤트 단위로 하나씩 호출 스택으로 옮긴겨 실행이 되어진다.
예시로 보면 작업1, 작업2, 작업3등 각자의 작업이 실행되는 구간과 다른 곳에서 실행되고 있는 공간이web api이고 실행되고 난 것은 콜백 큐로 받아서 이벤트 루프가 실행을 시킨다.
js는 콜 스택이 하나인 싱글 스레드이고 논블로킹으로 실행되기 때문에 함수의 비동기적인 실행이 가능하다.
hi를 출력하는 함수를 실행했을 때 해당 함수는 콜 스택에 쌓이게 되고 실행이 끝나고 나면 스택에서 빠져나가게 된다. 콜 스택에 어떠한 함수도 남아있지 않게 된다.
[web APIs]
1. setTimeout은 마찬가지로 함수이기에 콜 스택에 쌓인다.
2. setTimeout은 web apis를 호출하는 함수이기에 timer 함수를 호출한다.
3. setTimeout이 콜 스택에 쌓이고 web APIs에 함수가 등록된다.
4. 종료 된 후에는 콜 스택에 남겨 있던 함수는 빠져나간다.
5. 바로 다음줄의 코드가 실행이 된다.
6. 코드가 실행된 후 (콜 스택이 비어진 다음) web APIs에 남겨 있던 타이머 함수가 지정된 시간이 지난 후 콜백 큐로 넘어가게 된다.
7. 이벤트 루프는 콜 스택을 계속 바라보며 콜 스택이 비어있으면, 콜백 큐에 있던 함수를 콜 스택에 넘기게 된다.
8. 이벤트 루프는 콜 스택을 바라보고 있다. 콜 스택이 비어있음을 감시하고 콜백 큐에 있는 함수를 콜 스택으로 전달한다.
9. JS엔진은 다시 콜 스택을 비우기 위해 해당 함수를 실행시킨다.
10. 다른 function을 콜했기 때문에 cb1의 함수가 또다시 쌓이고 위에 쌓인 함수가 브라우저에 찍히게 된다.
11. 콜 스택에서 함수가 실행되면 빠져나가기에 해당 함수는 빠져나가고 마지막으로 남아있던 cb1도 다 실행을 시킨 후 콜 스택에서 빠져나가게 된다.
다음 정리
js가 어떻게 비동기적인 프로그램이 동작시키는건지 해당 흐름에 대해 자세하게 알 필요가 있다.
es6에서는 promise가 추가가 됐는데 promise의 실행방식은 콜백을 어떻게 비동기적으로 처리하게 됐는지에 대해 알아야한다.
- callback을 활용하여 비동기 호출 순서 제어하는 방법
- 비동기적으로 어떻게 콜백이 동작을 하는 것일까?: 콜백은 비동기적인 프로그래밍을 하는것에 있어서 스케줄링을 내 마음대로 할 수 있는 특징을 갖고 있다.
- function을 인자로 넘겨줄때 콜백이라고 지칭하는데 해당 콜백은 어떻게 비동기적으로 연관이 되는 것일까?
- 비동기적 프로그래밍에서 스케줄링 하는데 있어서 어떻게 콜백을 활용하여 스케줄링 하는 것인지
댓글