JavaScript has a concurrency model based on an event loop, which is responsible for executing the code, collecting and processing events, and executing queued sub-tasks.
by MDN
자바스크립트는 이벤트 루프를 사용해서 동시성(concurrency)을 지원한다고 한다. 그런데 잠깐! 자바스크립트는 싱글 스레드 아닌가?
맞다. 자바스크립트가 작업 중단되지 않고 동시에 다양한 작업을 할 수 있도록 지원하는 건 브라우저다. 브라우저에서 제공하는 Web API를 통해 비동기적으로 여러 작업을 동시에 처리할 수 있다.
객체(변수, 함수)등 메모리 할당이 일어난다.
실행될 코드가 한 줄씩 쌓인다.
비동기 처리 등을 담당한다.
비동기 처리가 끝나면 콜백 함수가 차례로 들어간다.
Callback Queue
에서 대기 중인 콜백 함수를 순서대로 Call Stack
에 할당한다.
Call Stack
에 추가된다.Call Stack
에서 빠져나간다.Web APIs
로 넘어간다. setTimeout은 값을 반환했기 때문에 Call Stack
에서 빠져나간다.Callback Queue
에 들어가 대기하기 시작한다.Event Loop
는 단 하나의 중요한 작업을 계속해서 수행하는데 바로 Call Stack
이 비어 있으면 Callback Queue
에서 대기 중인 첫 번째 콜백 함수를 Call Stack
으로 할당하는 것이다.Call Stack
을 빠져나간다.이론적인 설명이 막연하다면 퀴즈를 풀며 이해해보자.
다음 코드는 콘솔에 어떤 순서로 출력할까?
console.log("Hi");
setTimeout(function () {
console.log("callback");
}, 0);
console.log("Bye");
정답은...
Hi
Bye
callback
setTimeout의 두 번째 인자로 0초를 넣었는데도 Bye가 먼저 출력되는 것이 의아할 수 있다.
이때 0초는 0초 후에 콜백 함수가 실행되는 것을 보장하는 것이 아니라 0초 후에 콜백 함수를 Callback Queue
에 할당한다는 의미이다. 따라서 Call Stack
이 비워질 때까지 콜백 실행이 지연된다.
📢 이벤트 루프를 설명하기 위해 다양한 개념들이 소개되었는데 이를 매우 간략하게 설명하고 넘어갑니다!
In computer programming, single-threading is the processing of one command at a time.
by Wikipedia
한 번에 딱 한 가지 일만 한다.
Thread: Task A --> Task B
When a web app runs in a browser and it executes an intensive chunk of code without returning control to the browser, the browser can appear to be frozen. This is called blocking; the browser is blocked from continuing to handle user input and perform other tasks until the web app returns control of the processor.
by MDN
설명이 잘 되어 있지만 제공하는 데모로 직접 체험하는 걸 추천한다. 예제1, 예제2
계속해서 비동기에 대한 개념도 짚고 넘어가자.
browsers allow us to run certain operations asynchronously. Features like Promises allow you to set an operation running (e.g. the fetching of an image from the server), and then wait until the result has returned before running another operation.
by MDN
Main thread: Task A Task B
Promise: |__async operation__|
작업이 메인 스레드에서 처리되지 않기 때문에 블로킹이 발생하지 않는다. 하지만 작업의 실행 순서가 보장되지 않으므로 유의해야 한다.