네트워크 요청, 파일 입출력, 데이터베이스 처리와 같은 작업에서
동기와 비동기의 차이를 이해하면 더 효율적인 프로그램을 설계할 수 있다.
올해부터 주간 팀 내부 지식공유 학습회를 진행하고 있다.
첫 회차로 동기와 비동기 호출, 그리고 난이도가 높았던 실전 예제를 직접 다루었다.
(내부 소스를 직접 공유하려니 보안 문제가 발생하여, 비슷한 변형 예제와 플러터 소스로 자체 변경하였다.)
동기 호출은 호출된 함수가 완료될 때까지 호출한 함수가 기다리는 방식이다.
즉, 하나의 작업이 끝나야 다음 작업을 진행할 수 있다.
동기 호출의 특징
- 작업이 순차적으로 실행됨
- 실행 흐름이 직관적이며 이해하기 쉬움
- But 작업 완료를 기다리므로 응답 속도가 느릴 수 있음
반면 비동기 호출은 호출된 함수가 작업을 수행하는 동안 기다리지 않고 바로 다음 작업을 실행하는 방식이다.
비동기 호출의 특징
- 동시에 여러 작업을 수행할 수 있음
- 특정 작업이 완료되길 기다릴 필요가 없음
- 응답 속도가 빠르고 성능이 향상됨
- But 코드의 흐름이 복잡할 수 있음
파스타 / 피자 / 스테이크를 파는 이탈리안 레스토랑이 있다.
한 번에 하나씩밖에 하지 못하는 요리사는 동기 호출에,
여러 가지를 동시에 진행할 수 있는 요리사는 비동기 호출에 비유할 수 있다.
그리고 우리는 후자를 좀더 일머리가 좋은 사람으로 생각한다.
당연하다. 그래야 빨리 주문한 메뉴를 받아서 먹을 수 있다.
하지만 HTTP 요청을 보내고 응답받은 결과를 보여주는 상황에서는 응답을 '기다려야 한다.'
대부분의 코드들은 동기 방식으로 동작한다. 하지만
- 네트워크 요청하여 데이터 받아오기
- 파일 읽기 / 쓰기
- 데이터베이스 읽기 / 쓰기
와 같은 상황에서는 비동기 방식으로 동작한다.
플러터의 Future.delayed() 함수는 대표적인 비동기 방식으로 동작하는 코드이다.
n초 뒤에 실행할 것을 요구할 때에 사용한다.
void syncTask() {
print("작업 시작");
Future.delayed(Duration(seconds: 2), () {
print("작업 완료");
});
}
void main() {
print("호출 시작");
syncTask();
print("호출 종료");
}
syncTask에서 2초 딜레이를 걸어주어, 작업 완료가 2초 후에 찍히게 되는데, 그 전에 호출 종료가 먼저 찍힐 것이다.
호출 시작 -> 작업 시작 -> 호출 종료 -> 작업 완료 (2초 딜레이)
최근 버튼 딸깍 한 번이면
전년도 연말정산 인적공제에 입력한 가족들을 전부 불러와서
올해 연말정산 인적공제에 그대로 저장까지 다이렉트로 진행하는 기능을 만들었다.
버튼 클릭 시 전년도 데이터 조회 -> 저장 전 데이터 정합성 체크 -> 실제로 백엔드로 데이터를 넘겨 저장
3단계의 과정을 거치는데,
전년도 데이터를 조회에는 일정 시간이 걸릴 수밖에 없다.
그런데 그 시간을 기다리지 못하고 바로 뒷 로직으로 넘어가버려서
실제 데이터가 저장되지 않고 플로우를 타버리고 함수가 끝나 버리는 문제가 발생하였다.
그래서 데이터 조회에 딜레이를 걸어주는 방식으로 문제를 해결할 수 있었다.
보안 규정 때문에 소스를 반출할 수 없어 플러터 예제로 간단하게 리폼해보았다.
void syncTask() async{
print("조회 시작");
await Future.delayed(Duration(seconds: 2), () {
srchData();
print("조회 완료");
});
}
void main() {
print("데이터조회 호출 시작");
syncTask(); //데이터 조회
print("데이터조회 호출 종료");
checkSave(); //저장 전 정합성 체크
saveData(); //저장
}
플러터의 경우 await - async 를 통해 비동기 방식의 코드를 동기 방식으로 변경시킬 수 있다.
동기 vs 비동기: 언제 사용해야 할까?
동기 호출이 적합한 경우
- 작업이 빠르게 완료되는 경우 (예: 간단한 연산)
- 코드의 가독성과 유지보수가 중요한 경우
- 순차적으로 실행되는 것이 중요한 로직
비동기 호출이 적합한 경우
- 네트워크 요청, 파일 입출력, 데이터베이스 조회 등의 시간이 걸리는 작업
- 동시에 여러 개의 작업을 실행해야 하는 경우
- 성능 최적화가 필요한 경우
단순한 작업에서는 동기 호출이 직관적이고 이해하기 쉽지만,
네트워크 요청이나 대용량 데이터 처리와 같은 작업에서는 비동기 호출이 성능을 향상시킬 수 있다.
개발 상황에 따라 적절한 방식을 선택하여 효율적인 프로그램을 작성하는 것이 중요하다.
'study > geultto' 카테고리의 다른 글
코드트리 1개월 체험 후기 (2) _ 너 좀 달라졌다? (0) | 2025.02.02 |
---|---|
2024 회고: 나의 발자취와 새로운 시도들 (2) | 2025.01.05 |
Rebuilding is over, 그 다음은? - 스포츠의 사례로 보는 리빌딩 이후의 조직관리 과제들 (5) | 2024.12.22 |
구글 스프레드시트에서 ChatGPT API 활용하기: GPT for Sheets and Docs / Apps Script 구현 방법 (1) | 2024.11.24 |
자유 운동 기록 프로그램 설계에 대한 고민 : 효율성/확장성 관점 (5) | 2024.11.10 |
댓글