동기(synchronous) 프로그래밍과 비동기(asynchronous) 프로그래밍의 주요 차이점은 작업이 처리되는 순서와 방식입니다.
동기 프로그래밍
- 순차적 실행: 동기 프로그래밍에서는 하나의 작업이 완료될 때까지 다음 작업이 시작되지 않습니다. 즉, 모든 작업이 순차적으로 실행됩니다.
- 블로킹: 동기 작업은 이전 작업이 완료될 때까지 기다리기 때문에, 어떤 작업이 오래 걸리면 그 동안 다른 작업이 진행되지 않습니다.
예시 (동기 코드):
console.log('Start');
function fetchDataSync() {
// 오랜 시간이 걸리는 작업
for (let i = 0; i < 1000000000; i++) {}
return { name: 'John', age: 30 };
}
const data = fetchDataSync();
console.log('Data received:', data);
console.log('End');
위 코드에서 fetchDataSync 함수가 실행될 때까지 다음 코드가 실행되지 않습니다. 따라서 콘솔 출력은 순차적으로 'Start', 'Data received:', 'End'가 됩니다.
비동기 프로그래밍
- 비순차적 실행: 비동기 프로그래밍에서는 하나의 작업이 시작된 후, 그 작업이 완료될 때까지 기다리지 않고 다음 작업을 바로 실행합니다. 비동기 작업이 완료되면 콜백 함수나 프라미스를 통해 결과를 처리합니다.
- 논블로킹: 비동기 작업은 이전 작업이 완료될 때까지 기다리지 않으므로, 다른 작업이 동시에 실행될 수 있습니다.
예시 (비동기 코드):
console.log('Start');
function fetchDataAsync(callback) {
setTimeout(() => {
const data = { name: 'John', age: 30 };
callback(data);
}, 2000);
}
fetchDataAsync((data) => {
console.log('Data received:', data);
});
console.log('End');
위 코드에서 fetchDataAsync 함수는 비동기적으로 데이터를 가져오므로, setTimeout 안의 콜백 함수가 실행되기 전에 다음 코드 (console.log('End'))가 먼저 실행됩니다. 따라서 콘솔 출력은 'Start', 'End', 'Data received:' 순서로 됩니다.
요약
- 동기 프로그래밍: 순차적 실행, 블로킹 방식. 하나의 작업이 끝날 때까지 다음 작업을 시작하지 않음.
- 비동기 프로그래밍: 비순차적 실행, 논블로킹 방식. 작업이 완료될 때까지 기다리지 않고 다음 작업을 바로 시작하며, 작업 완료 후 결과를 처리.
따라서, 동기 프로그래밍이 순차적이고, 비동기 프로그래밍은 순차적이지 않습니다. 비동기 프로그래밍에서는 작업이 완료되는 순서와 관계없이 여러 작업을 동시에 진행할 수 있습니다.
자바스크립트는 기본적으로 동기적이며, 단일 스레드에서 실행됩니다. 이는 기본적으로 자바스크립트 코드가 순차적으로 실행된다는 것을 의미합니다. 즉, 한 줄의 코드가 실행을 완료한 후에야 다음 줄의 코드가 실행됩니다. 그러나 자바스크립트는 비동기 프로그래밍을 지원하기 위한 여러 가지 메커니즘도 제공합니다.
기본적인 동기적 실행
다음 예시는 자바스크립트의 기본적인 동기적 실행 방식을 보여줍니다:
console.log('Start');
function fetchDataSync() {
// 오랜 시간이 걸리는 작업
for (let i = 0; i < 1000000000; i++) {}
return { name: 'John', age: 30 };
}
const data = fetchDataSync();
console.log('Data received:', data);
console.log('End');
위 예제에서 코드는 순차적으로 실행됩니다. fetchDataSync 함수가 완료될 때까지 console.log('End')는 실행되지 않습니다.
자바스크립트의 비동기 메커니즘
자바스크립트는 비동기 작업을 처리하기 위해 여러 가지 메커니즘을 제공합니다. 가장 일반적인 방법은 콜백 함수, 프라미스(Promise), 그리고 async/await 구문입니다. 또한, 자바스크립트의 런타임 환경인 브라우저나 Node.js는 이벤트 루프를 통해 비동기 작업을 처리합니다.
1. 콜백 함수
콜백 함수는 비동기 작업이 완료된 후 호출되는 함수입니다.
console.log('Start');
function fetchDataAsync(callback) {
setTimeout(() => {
const data = { name: 'John', age: 30 };
callback(data);
}, 2000);
}
fetchDataAsync((data) => {
console.log('Data received:', data);
});
console.log('End');
위 예제에서 setTimeout 함수는 비동기적으로 작동하므로, 'End'가 'Data received:'보다 먼저 출력됩니다.
2. 프라미스(Promise)
프라미스는 비동기 작업의 결과를 나타내는 객체입니다.
console.log('Start');
function fetchDataAsync() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: 'John', age: 30 };
resolve(data);
}, 2000);
});
}
fetchDataAsync().then((data) => {
console.log('Data received:', data);
});
console.log('End');
위 예제에서 프라미스를 사용하여 비동기 작업을 처리합니다. 'End'가 'Data received:'보다 먼저 출력됩니다.
3. async/await
async/await는 프라미스를 더 쉽게 사용할 수 있게 해줍니다.
console.log('Start');
function fetchDataAsync() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const data = { name: 'John', age: 30 };
resolve(data);
}, 2000);
});
}
async function main() {
const data = await fetchDataAsync();
console.log('Data received:', data);
}
main();
console.log('End');
위 예제에서 async/await를 사용하여 비동기 작업을 동기 작업처럼 작성할 수 있습니다. 그러나 실제로는 비동기적으로 작동하므로 'End'가 'Data received:'보다 먼저 출력됩니다.
요약
- 자바스크립트는 기본적으로 동기적으로 작동합니다.
- 자바스크립트는 비동기 작업을 처리하기 위한 메커니즘을 제공합니다: 콜백 함수, 프라미스, async/await.
- 자바스크립트 런타임 환경(브라우저, Node.js)은 이벤트 루프를 통해 비동기 작업을 처리합니다.
비동기 프로그래밍을 통해 자바스크립트는 네트워크 요청, 파일 입출력 등 시간이 오래 걸리는 작업을 효율적으로 처리할 수 있습니다.