1. 기본적으로 동기적으로 처리되는 자바스크립트
자바스크립트는 단일 스레드로 동작하기 때문에, 한 번에 하나의 작업만 처리할 수 있습니다. 동기적으로 처리된다는 것은 각 작업이 순차적으로 실행되고, 이전 작업이 완료되기 전까지는 다음 작업이 실행되지 않는다는 의미입니다. 예를 들어, 동기적 코드에서는 블로킹(Blocking)이 발생하여 시간이 오래 걸리는 작업이 있다면 그 작업이 완료될 때까지 다른 코드가 실행되지 않습니다.
• 동기적 처리 예시:
console.log("첫 번째 작업 시작");
for (let i = 0; i < 1000000000; i++) {} // 시간이 오래 걸리는 작업
console.log("두 번째 작업 시작");
위 코드는 for 루프가 끝나기 전까지 “두 번째 작업 시작” 로그가 출력되지 않습니다. 동기적인 코드이기 때문에, 첫 번째 작업이 끝나야 다음 작업이 실행됩니다.
2. 비동기 처리
자바스크립트의 단일 스레드 특성상, 블로킹 작업을 효율적으로 처리하기 위해 비동기 처리가 필요합니다. 비동기 처리는 작업이 완료될 때까지 기다리지 않고, 그 작업이 백그라운드에서 진행되는 동안 다른 작업을 계속 처리할 수 있게 해줍니다.
• 브라우저에서는 Web APIs를 통해 비동기 작업이 이루어지며,
• Node.js에서는 Node APIs를 사용해 비동기 작업을 처리합니다.
2.1 Web APIs (브라우저 환경)
브라우저에서 비동기 작업은 자바스크립트 엔진(V8 같은)이 아닌, Web APIs를 통해 처리됩니다. 자바스크립트는 비동기 함수(예: setTimeout, fetch, XMLHttpRequest 등)를 호출하면, 이를 Web API에 넘겨서 처리하게 됩니다.
• Web API가 처리하는 동안 자바스크립트는 다른 작업을 계속 수행하며, Web API에서 작업이 완료되면 콜백 함수를 이벤트 루프를 통해 콜백 큐로 보내고, 콜 스택이 비워지면 콜백 큐에 있는 콜백이 실행됩니다.
• 예시: Web API와 비동기 처리:
console.log("첫 번째 작업 시작");
setTimeout(() => {
console.log("비동기 작업 완료");
}, 2000);
console.log("두 번째 작업 시작");
이 예시에서 setTimeout은 비동기 함수로, 브라우저의 Web API에서 처리됩니다. setTimeout이 호출된 후 바로 자바스크립트는 “두 번째 작업 시작”을 출력하고, Web API에서 2초 후에 콜백 함수를 이벤트 루프를 통해 다시 자바스크립트 런타임으로 보내서 실행합니다.
2.2 Node.js APIs (서버 환경)
Node.js에서도 자바스크립트의 비동기 처리를 지원하기 위해 다양한 Node APIs를 제공합니다. Node.js의 비동기 작업은 파일 시스템 접근, 네트워크 요청, 데이터베이스 작업 등을 비동기로 처리할 수 있게 해주며, 이러한 작업 역시 이벤트 루프에 의해 관리됩니다.
Node.js 환경에서 비동기 작업을 수행할 때, 자바스크립트 코드가 비동기 API를 호출하면 해당 작업은 Node.js의 비동기 I/O 시스템으로 넘어가며, 작업이 완료된 후 콜백 함수가 이벤트 루프를 통해 실행됩니다.
• 예시: Node.js에서 비동기 파일 읽기:
const fs = require('fs');
console.log("파일 읽기 시작");
fs.readFile('file.txt', 'utf8', (err, data) => {
if (err) throw err;
console.log(data);
});
console.log("다른 작업 수행 중");
위 코드에서 fs.readFile은 비동기적으로 파일을 읽는 Node API입니다. 파일 읽기가 완료되기 전까지 자바스크립트는 계속해서 다른 작업(여기서는 “다른 작업 수행 중”)을 수행하며, 파일 읽기가 완료되면 콜백 함수가 실행되어 파일 내용이 출력됩니다.
3. 이벤트 루프(Event Loop)와 비동기 처리의 동작 원리
비동기 함수들은 자바스크립트의 이벤트 루프(Event Loop) 메커니즘을 통해 처리됩니다. 이벤트 루프는 자바스크립트가 비동기 작업과 콜백을 처리하는 방식의 핵심입니다.
3.1 이벤트 루프의 작동 과정
1. 콜 스택(Call Stack): 자바스크립트의 모든 실행 컨텍스트가 여기에 쌓입니다. 함수가 호출될 때마다 새로운 실행 컨텍스트가 콜 스택에 쌓이고, 함수 실행이 완료되면 스택에서 제거됩니다.
2. Web API (또는 Node API): 비동기 작업은 Web API 또는 Node API에 의해 백그라운드에서 처리됩니다.
3. 콜백 큐(Callback Queue): Web API에서 완료된 비동기 작업의 콜백 함수는 콜백 큐로 전달됩니다.
4. 이벤트 루프(Event Loop): 이벤트 루프는 콜 스택이 비었을 때 콜백 큐에 있는 함수를 콜 스택으로 가져와 실행합니다.
3.2 예시로 설명하는 이벤트 루프의 작동
console.log('1'); // 동기 작업
setTimeout(() => {
console.log('2'); // 비동기 작업, 2초 후 실행
}, 2000);
console.log('3'); // 동기 작업
• 단계 1: console.log('1')은 동기적으로 실행되어 콜 스택에 쌓이고, 바로 출력됩니다.
• 단계 2: setTimeout은 Web API로 넘겨져 2초 동안 백그라운드에서 실행됩니다.
• 단계 3: console.log('3')이 동기적으로 실행되어 출력됩니다.
• 단계 4: 2초가 지나면 setTimeout의 콜백 함수가 콜백 큐로 전달됩니다.
• 단계 5: 이벤트 루프는 콜 스택이 비었는지 확인하고, 비었다면 콜백 큐에서 대기 중인 콜백 함수를 콜 스택으로 가져와 실행합니다.
결과적으로 “1”, “3”, “2” 순으로 출력됩니다.
참고영상
https://www.youtube.com/watch?v=eiC58R16hb8
4. 정리
• 자바스크립트는 단일 스레드로 동작하며, 기본적으로 동기적으로 처리됩니다. 그러나 Web APIs(브라우저 환경)와 Node.js APIs(서버 환경)를 통해 비동기 작업을 처리할 수 있습니다.
• 자바스크립트는 비동기 함수 호출 시 이벤트 루프와 콜백 큐를 통해 비동기 작업이 완료된 후 해당 작업을 처리합니다.
• 브라우저에서는 Web APIs(setTimeout, fetch, XMLHttpRequest 등)를 통해 비동기 처리가 이루어지며, Node.js에서는 Node APIs(fs, http, net 등)를 통해 비동기 처리가 이루어집니다.
• 이벤트 루프는 자바스크립트의 비동기 처리 메커니즘의 핵심이며, 비동기 작업의 콜백 함수를 적절히 관리하여 비동기적으로 실행할 수 있도록 합니다.
이러한 메커니즘 덕분에 자바스크립트는 비동기 작업을 효과적으로 처리할 수 있으며, 특히 웹 애플리케이션과 서버 애플리케이션에서 높은 성능을 유지할 수 있습니다.
'JavaScript' 카테고리의 다른 글
[JS] 얕은복사, 깊은복사 (2) | 2024.09.08 |
---|---|
[JS] Promise (0) | 2024.09.08 |
[JS] Callback (0) | 2024.09.08 |
[JS] 함수와 클래스(this) (0) | 2024.09.08 |
[JS] Scope (0) | 2024.09.08 |