React에서 개발을 하다 보면 네트워크 요청이나 데이터 처리 시 async와 await를 사용하게 됩니다. 하지만 막상 코드를 작성하다 보면, 왜 이러한 비동기 처리를 사용하는지, 동기와 비동기의 정확한 개념이 무엇인지 궁금해지곤 합니다. 저 역시 비슷한 의문을 품고 있었는데요, 최근 개발 중 async와 await를 사용하는 이유를 정확히 이해하지 못하고 있다는 것을 깨달았습니다.
그래서 이번 기회에 **동기(Synchronous)와 비동기(Asynchronous)**의 차이를 제대로 알아보고, 프론트엔드와 백엔드에서 각각 언제 어떻게 사용해야 하는지에 대해 정리해보려고 합니다. 특히, 프론트엔드 개발에서 비동기 처리가 거의 필수적인 이유와 백엔드에서도 동기와 비동기를 상황에 따라 어떻게 활용하는지 알아보겠습니다.
■ 동기(Synchronous)와 비동기(Asynchronous)란?
1 동기(Synchronous)
- 설명: 동기 방식은 작업이 순차적으로 진행되며, 하나의 작업이 완료될 때까지 다음 작업이 실행되지 않습니다. 즉, 작업이 완료될 때까지 프로그램의 흐름이 멈추어 기다립니다.
- 장점: 코드 작성이 간단하고 논리적인 흐름을 따라가기가 쉽습니다.
- 단점: 하나의 작업이 오래 걸리면 전체 프로세스가 멈추어 다른 작업을 수행할 수 없습니다.
2 비동기(Asynchronous)
- 설명: 비동기 방식은 특정 작업이 완료될 때까지 기다리지 않고 다음 작업을 진행합니다. 결과가 나올 때 콜백 함수나 이벤트를 통해 처리합니다.
- 장점: 작업이 병렬로 처리되므로 시스템의 응답성이 높아지고 자원을 효율적으로 사용할 수 있습니다.
- 단점: 코드가 복잡해질 수 있고, 비동기적으로 작동하는 여러 작업의 흐름을 관리하는 것이 어렵습니다.
■프론트엔드에서 동기와 비동기
프론트엔드 개발, 특히 JavaScript 기반의 React, Angular, Vue와 같은 라이브러리/프레임워크에서 비동기가 매우 중요한 이유는 사용자 경험과 직접적으로 연결되기 때문입니다.
1. 프론트엔드에서 동기 방식의 사용
- 프론트엔드에서는 동기 방식이 거의 사용되지 않습니다. 그 이유는 UI가 사용자 입력에 빠르게 반응해야 하기 때문입니다.
- 사용하지 않는 이유: 동기 방식으로 네트워크 요청이나 대용량 데이터 처리를 하면 요청이 완료될 때까지 UI가 멈춥니다. 이는 앱의 응답성을 저하시켜 사용자 경험을 크게 해칩니다.
alert('이 알림이 닫힐 때까지 다음 코드는 실행되지 않습니다.');
console.log('이 메시지는 알림이 닫힌 후에 출력됩니다.');
위 코드는 동기적으로 작동하는 alert() 함수로 인해 사용자 입력을 기다리며, 그동안 UI는 아무런 작업을 하지 못합니다.
2. 프론트엔드에서 비동기 방식의 사용
- 비동기 방식은 프론트엔드에서 네트워크 요청, 데이터 로딩, 타이머 등의 작업을 처리할 때 주로 사용됩니다.
- API 호출 시 비동기 사용: 프론트엔드에서 백엔드 API를 호출할 때, 네트워크 응답 시간이 불확실하기 때문에 이를 비동기로 처리해야 앱의 다른 부분이 원활하게 동작할 수 있습니다.
const fetchData = async () => {
try { const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log('Data received:', data);
} catch (error) {
console.error('Error fetching data:', error);
}
};
위 코드는 async/await를 사용해 비동기적으로 데이터를 요청합니다. 요청이 완료되기 전에도 앱의 다른 부분이 동작하므로 사용자에게 멈춤 현상이 발생하지 않습니다.
■ 백엔드에서 동기와 비동기
백엔드에서는 프론트엔드보다 조금 더 유연하게 동기와 비동기를 선택적으로 사용할 수 있습니다.
1 백엔드에서 동기 방식의 사용
- 간단한 작업: 동기 방식은 파일 입출력, 데이터베이스 쿼리와 같은 간단하고 즉각적인 작업을 처리할 때 주로 사용됩니다. 예를 들어, 애플리케이션의 초기 설정을 로드하거나, 간단한 연산을 처리할 때 동기 방식이 더 직관적이고 간편할 수 있습니다.
- 순차적인 작업: 여러 작업이 순차적으로 진행되어야 하고, 한 작업의 결과가 다음 작업에 필요할 때 동기 방식이 적합합니다.
public void fetchDataSync() {
// 동기적으로 데이터베이스에 쿼리
String result = database.query("SELECT * FROM table");
System.out.println("Query result: " + result);
}
이 코드는 데이터베이스에 쿼리하는 동안 다른 작업을 진행하지 않습니다. 이 방법은 코드가 간단해지는 장점이 있지만, 요청이 오래 걸리면 다른 작업을 막는 단점이 있습니다.
2 백엔드에서 비동기 방식의 사용
- 대규모 작업: 파일 입출력, 네트워크 요청, 데이터베이스 쿼리 등 시간이 오래 걸리거나 외부 서비스와 통신하는 작업은 비동기적으로 처리하는 것이 효율적입니다.
- 동시 처리: 서버는 다수의 클라이언트 요청을 동시에 처리해야 합니다. 비동기를 사용하면 여러 요청을 비슷한 시점에 처리하여 시스템의 자원을 효율적으로 사용할 수 있습니다. CompletableFuture를 사요하여 비동기처리 할 수 있습니다.
import java.util.concurrent.CompletableFuture;
public void fetchDataAsync() {
CompletableFuture.runAsync(() -> {
String result = database.query("SELECT * FROM table");
System.out.println("Query result: " + result);
});
System.out.println("이 코드는 비동기 작업 후에도 실행됩니다.");
}
이 코드는 비동기적으로 데이터베이스 쿼리를 실행하며, 쿼리 결과를 기다리지 않고 다음 코드를 진행합니다.
■ 정리
- 프론트엔드에서 비동기 방식이 필수인 이유: 프론트엔드는 사용자와 직접 상호작용하는 UI를 담당하므로, 네트워크 요청이나 데이터 로딩을 동기 방식으로 처리하면 앱이 멈추고 사용자 경험이 나빠집니다. 비동기를 사용하면 이러한 문제를 해결할 수 있습니다.
- 백엔드에서의 동기와 비동기: 백엔드에서는 동기 방식이 적합한 상황도 있습니다. 초기화나 간단한 연산 등 즉각적인 처리가 필요한 경우에는 동기 방식이 더 직관적입니다. 하지만, 네트워크 요청, 데이터베이스 쿼리와 같은 대규모 작업을 처리하거나 동시에 다수의 요청을 처리할 때는 비동기를 사용해야 합니다.
동기와 비동기는 각각의 특성과 장단점을 가지고 있으며, 이를 언제 어떻게 사용하느냐에 따라 애플리케이션의 성능과 사용자 경험이 크게 달라집니다. 프론트엔드에서는 대부분 비동기를 사용해야 응답성이 높은 UI를 제공할 수 있고, 백엔드에서는 상황에 따라 동기와 비동기를 적절히 사용하여 효율적인 시스템을 구축할 수 있습니다.
'WEB' 카테고리의 다른 글
[웹소켓] 실시간 데이터 전송하기(feat.Java) (0) | 2025.01.20 |
---|---|
[web] Safari에서 Universal Link와 서버 리다이렉션의 작동 원리 분석 (0) | 2024.08.12 |
[web] 딥링크(Universal Link) (0) | 2024.07.29 |