동기(synchronous)란, 어떤 작업을 실행할 때 그 작업이 끝나기를 기다리는 방식을 의미합니다. 즉, 작업이 완료될 때까지 다음 코드의 실행을 멈추고 기다리는 것입니다. 이러한 방식은 작업의 순서를 보장하고, 작업이 끝날 때까지 결과를 기다리는 것이 가능합니다.
비동기(asynchronous)란, 어떤 작업을 실행할 때 그 작업이 완료되지 않더라도 다음 코드를 실행하는 방식을 의미합니다. 즉, 작업이 완료되지 않았더라도 결과를 기다리지 않고 다음 코드를 실행하게 됩니다. 이러한 방식은 작업이 오래 걸리는 경우 시간을 절약하고, 병렬적인 작업 처리가 가능합니다.
동기 방식으로 파일을 읽는다면 파일을 읽기 시작한 이후에 다음 코드를 실행하지 않고 파일이 읽혀지기를 기다리게 됩니다. 반면에 비동기 방식으로 파일을 읽는다면 파일을 읽는 작업이 실행되는 동안 다른 작업을 수행할 수 있습니다.
자바스크립트는 싱글 스레드(Single Thread) 기반의 프로그래밍 언어입니다. 하나의 스레드에서 모든 작업을 처리하도록 되어 있기 때문에, 한 번에 하나의 작업만 처리할 수 있습니다. 그래서 자바스크립트에서 동기 방식으로 처리를 하게 되면, 이전 작업이 완료될 때까지 다음 작업을 처리할 수 없습니다. 이러한 문제점을 해결하기 위해 자바스크립트에서는 비동기 처리가 필요합니다.
function test() {
for (let i = 0; i < 10000; i++) {
console.log(1);
}
console.log(2);
}
// 콘솔에 2가 찍히려면 1만 번의 1이 찍힐 때까지 기다려야 합니다.
비동기 처리를 통해 자바스크립트는 하나의 스레드에서도 병렬적으로 여러 작업을 처리할 수 있습니다. 예를 들어, 네트워크 통신을 비동기 방식으로 처리하면, 서버로부터 데이터를 받아오는 동안에도 다른 작업을 처리할 수 있으며, 데이터를 받아오는 작업이 완료되면 해당 작업을 처리할 수 있습니다.
웹 페이지의 반응성 향상: 사용자가 요청한 작업이 완료될 때까지 기다리는 것은 사용자 경험을 저해시키게 됩니다. 따라서, 비동기 처리를 통해 사용자의 요청에 빠르게 반응할 수 있도록 해야 합니다.
네트워크 통신: 웹 애플리케이션에서는 서버와의 데이터 통신이 필요합니다. 동기적인 처리를 하게 되면 응답을 기다리는 동안 다른 작업을 수행할 수 없기 때문에 웹 페이지의 반응성이 떨어질 수 있습니다. 따라서, 비동기적으로 데이터를 받아오는 것이 웹 페이지의 성능을 향상시키는데 도움이 됩니다.
병렬 처리: 비동기 처리를 통해 여러 작업을 동시에 처리할 수 있습니다. 이를 통해 시간이 오래 걸리는 작업을 병렬적으로 처리할 수 있으며, 결과적으로 전체 작업 시간을 단축시킬 수 있습니다.
에러 처리: 비동기적으로 처리할 때 에러가 발생하면, 해당 에러를 쉽게 처리할 수 있습니다. 에러 발생 시, 에러를 처리할 수 있는 콜백 함수를 실행하거나, 에러를 캐치하여 처리할 수 있어 프로그램의 안정성을 높일 수 있습니다.
async와 await는 ECMAScript 8(ES2017)부터 도입된 자바스크립트의 비동기 처리 방식입니다. 이를 사용하면 비동기 코드를 마치 동기 코드처럼 작성할 수 있어 가독성이 높아지고 에러 처리가 간단해집니다.
async/await는 프로미스 기반으로 동작합니다. async 함수 내부에서 await 키워드를 사용하면 해당 비동기 작업이 완료될 때까지 코드 실행을 일시 중지하고 결과를 기다린 다음, 그 결과를 반환합니다. 이를 통해 프로미스의 then/catch/finally 후속 처리 메서드를 사용하지 않고도 마치 동기 처리처럼 프로미스를 사용할 수 있습니다.
async 키워드는 함수 앞에 붙여 해당 함수가 비동기 함수임을 나타내며, await 키워드는 비동기 함수의 실행 결과를 기다리는 데 사용됩니다. await 키워드는 반드시 async 함수 내부에서 사용해야 하며, async 함수는 언제나 프로미스를 반환합니다.
async function getData() {
const response = await fetch('/api');
const data = await response.json();
return data;
}
해당 함수는 async 함수 getData를 정의하고, fetch 함수를 사용하여 URL에서 데이터를 가져오고, 해당 데이터를 JSON으로 파싱하는 작업을 비동기적으로 수행한다. await를 사용하여 fetch와 json() 메서드를 기다리고, 데이터를 반환한다.
async function getData() {
try {
const response = await fetch('/api');
const data = await response.json();
return data;
} catch (error) {
console.error(error);
}
}
await 키워드는 Promise 객체가 완료될 때까지 코드 실행을 일시 중지하므로, try-catch 블록 안에서 사용하여 에러 처리를 할 수 있다. fetch에서 네트워크 에러가 발생할 경우, await 이후의 코드는 실행되지 않으며, catch 블록으로 제어가 넘어가 에러를 처리할 수 있다. await 키워드는 반드시 프로미스 앞에서 사용해야 한다.
async function fetchAllData() {
try {
const [data1, data2] = await Promise.all([
fetch('/api/data1').then(response => response.json()),
fetch('/api/data2').then(response => response.json())
]);
console.log(data1, data2);
} catch (error) {
console.error("Error fetching data:", error);
}
}
fetchAllData();
두 개의 비동기 작업을 병렬로 실행하고, 모든 작업이 완료될 때까지 기다린 후 결과를 반환한다. Promise.all을 사용하면 여러 비동기 작업을 동시에 처리할 수 있어 성능을 향상시킬 수 있다.
https://ko.javascript.info/async-await
https://velog.io/@tosspayments/예제로-이해하는-awaitasync-문법
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/async_function
https://trustmitt.tistory.com/85