Flutter에서의 비동기 처리(Async/Await) 이해하기

Baek Dong Hyun·2025년 2월 23일
1

1. 비동기 처리가 뭐지?

비동기 처리(Asynchronous Processing)란 작업이 완료될 때까지 기다리지 않고, 다음 작업을 진행하는 방식을 의미합니다.

쉽게 말해, 우리가 음식을 주문하고 조리가 끝날 때까지 가만히 기다리는 것이 아니라, 다른 일을 하다가 음식이 나오면 다시 돌아와서 먹는 것과 같은 원리입니다.

Flutter에서는 네트워크 요청, 파일 읽기, 데이터베이스 조회 등 시간이 오래 걸리는 작업을 효율적으로 처리하기 위해 비동기 처리를 사용합니다.


2. 그럼 동기와 비동기의 차이는?

처리 방식설명예시
동기 처리(Synchronous)작업이 완료될 때까지 기다린 후 다음 작업을 실행음식을 주문하고 조리가 끝날 때까지 기다리는 것
비동기 처리(Asynchronous)작업이 끝날 때까지 기다리지 않고, 다음 작업을 진행음식을 주문한 후 다른 일을 하다가 완료되면 먹는 것

동기 처리 코드 예제

void main() {
  print("1. 데이터를 요청합니다.");
  fetchData(); // 시간이 오래 걸리는 작업
  print("3. 데이터를 화면에 출력합니다.");
}

void fetchData() {
  for (int i = 0; i < 1000000000; i++) {} // 시간이 걸리는 연산
  print("2. 데이터 요청 완료!");
}

출력 결과:

1. 데이터를 요청합니다.
2. 데이터 요청 완료!
3. 데이터를 화면에 출력합니다.

위와 같이 fetchData()가 완료될 때까지 다음 코드가 실행되지 않습니다.

비동기 처리 코드 예제 (async/await 사용)

void main() async {
  print("1. 데이터를 요청합니다.");
  await fetchData(); // 비동기 처리
  print("3. 데이터를 화면에 출력합니다.");
}

Future<void> fetchData() async {
  await Future.delayed(Duration(seconds: 2));
  print("2. 데이터 요청 완료!");
}

출력 결과:

1. 데이터를 요청합니다.
(2초 후)
2. 데이터 요청 완료!
3. 데이터를 화면에 출력합니다.

비동기 코드를 사용하면 작업이 끝날 때까지 기다리지 않고 다른 작업을 수행할 수 있습니다.


3. 비동기 처리 코드는 어떻게 작성해야 돼?

Flutter에서 비동기 처리는 주로 Future, async/await, 그리고 then을 사용하여 구현합니다.

✅ Future를 사용한 비동기 코드

Future<String> fetchData() {
  return Future.delayed(Duration(seconds: 2), () => "데이터 로드 완료");
}

📌 Future는 비동기 작업의 결과를 나타내는 객체입니다.

  • Future는 한 번만 값을 반환하며, 해당 작업이 완료되면 값을 받을 수 있습니다.
  • then 또는 await을 사용하여 결과를 처리할 수 있습니다.

✅ async/await을 사용한 비동기 코드

void main() async {
  print("데이터를 불러오는 중...");
  String data = await fetchData();
  print(data);
}

📌 async/await은 Future를 더 직관적으로 사용할 수 있도록 도와줍니다.

  • async 키워드를 함수에 추가하면 비동기 함수가 됩니다.
  • await 키워드를 사용하면 Future가 완료될 때까지 기다렸다가 실행됩니다.
  • try-catch 블록을 사용하여 오류를 쉽게 처리할 수 있습니다.

✅ then을 사용한 비동기 코드

void main() {
  print("데이터를 불러오는 중...");
  fetchData().then((data) {
    print(data);
  });
}

📌 then() 메서드는 Future의 결과를 받아 처리할 때 사용됩니다.

  • await을 사용할 수 없는 경우(예: 기존의 콜백 방식) 유용하게 사용됩니다.
  • 하지만 코드가 길어질수록 then 체인이 복잡해지고 가독성이 떨어질 수 있습니다.

Future vs async/await vs then 비교

방식장점단점
Future비동기 작업을 실행하고 then을 사용해 결과 처리 가능여러 개의 then 체인이 생기면 가독성이 떨어짐
async/await동기 코드처럼 직관적으로 작성 가능, 가독성이 뛰어남await은 async 함수 내에서만 사용 가능
then콜백 스타일로 비동기 처리 가능, 간단한 작업에 적합중첩되면 코드가 복잡해짐 (콜백 지옥 발생 가능)

4. 그렇다면 언제 사용해야 될까?

비동기 처리는 다음과 같은 경우에 사용됩니다.

  • 네트워크 요청 (API 호출): 데이터를 서버에서 가져올 때
  • 파일 입출력 (File I/O): 기기 내부에서 파일을 읽고 쓸 때
  • 데이터베이스 조회: SQLite나 Firebase와 같은 데이터베이스에서 데이터를 가져올 때
  • 애니메이션 처리: 일정 시간이 걸리는 애니메이션을 실행할 때

비동기 처리는 사용자의 경험을 부드럽게 만들어주며, UI가 멈추지 않도록 도와줍니다.


5. 모든 코드를 다 비동기로 작성하면 안돼?

비동기 처리는 매우 강력하지만, 모든 코드를 비동기로 작성하면 오히려 불필요한 복잡성이 증가할 수 있습니다.

📌 주의해야 할 점

  • 필요한 경우에만 비동기 처리 사용 (예: 네트워크 요청, 데이터 로드 등)
  • UI 관련 작업은 동기적으로 유지 (예: 버튼 클릭 이벤트, 간단한 연산 등)
  • Future를 남발하지 않기 (불필요한 Future 사용은 코드 가독성을 떨어뜨림)

따라서, 비동기 처리는 필요할 때만 신중하게 사용해야 합니다.


6. 추가적으로 알아두면 좋은 개념

비동기 처리와 관련하여 알아두면 좋은 개념들은 다음과 같습니다.

✅ Stream: 지속적인 데이터 흐름 처리

Future는 한 번의 작업을 처리하지만, Stream여러 개의 데이터를 순차적으로 처리할 수 있습니다.

Stream<int> countStream() async* {
  for (int i = 0; i < 5; i++) {
    await Future.delayed(Duration(seconds: 1));
    yield i;
  }
}

✅ Isolate: 멀티스레딩 활용

Flutter는 단일 스레드에서 실행되지만, Isolate를 사용하면 별도의 스레드에서 작업을 실행할 수 있습니다.

import 'dart:isolate';

void backgroundTask(SendPort sendPort) {
  sendPort.send("백그라운드 작업 완료!");
}

7. 마무리

비동기 처리는 Flutter 개발에서 필수적인 개념으로, 앱의 성능과 사용자 경험을 향상시키는 데 중요한 역할을 합니다.

  • 동기 처리와 비동기 처리의 차이를 이해하고, 필요할 때 적절히 사용해야 하며,
  • async/await, Future, Stream 등의 개념을 숙지하여 다양한 상황에서 비동기 처리를 활용할 수 있어야 합니다.
profile
안녕하세요.

0개의 댓글

관련 채용 정보