중급

Future와 async/await

한 번 완료되는 비동기 작업을 Future로 표현하고 async/await로 읽기 쉽게 다룹니다.

개념 먼저 보기

Future와 async/await의 기본 개념부터 잡기

Future와 async/await 문서는 먼저 용어의 뜻을 잡고, 그 다음 Flutter 코드에서 어디에 쓰이는지 연결해서 읽는 것이 좋습니다.

아래 항목들은 이 문서에서 다루는 내용을 작은 단위로 나눈 것입니다. 각 항목을 읽은 뒤 예제를 보면 코드가 훨씬 덜 추상적으로 느껴집니다.

종류별로 하나씩

Future와 async/await에서 나눠 볼 핵심 요소

Future

네트워크 요청, 파일 읽기, 타이머처럼 나중에 끝나는 작업을 표현합니다.

언제 쓰나: async 함수는 자동으로 Future를 반환합니다.

Flutter에서: await는 Future가 완료될 때까지 현재 async 함수의 실행을 잠시 멈춥니다.

// Future와 async/await 예제입니다.
// 먼저 코드의 큰 흐름을 보고, 주석을 따라 각 줄의 역할을 확인하세요.
Future<List<String>> fetchTopics() async {
  await Future.delayed(const Duration(milliseconds: 300));
  return ['Dart', 'Widget', 'State'];
}

오류 처리

try/catch로 비동기 오류를 처리합니다.

언제 쓰나: UI에서는 로딩, 성공, 실패 상태를 명확히 나눕니다.

Flutter에서: finally는 성공과 실패와 관계없이 정리 작업을 실행할 때 사용합니다.

// Future와 async/await 예제입니다.
// 먼저 코드의 큰 흐름을 보고, 주석을 따라 각 줄의 역할을 확인하세요.
Future<List<String>> fetchTopics() async {
  await Future.delayed(const Duration(milliseconds: 300));
  return ['Dart', 'Widget', 'State'];
}

부연 설명

Future

  • 네트워크 요청, 파일 읽기, 타이머처럼 나중에 끝나는 작업을 표현합니다.
  • async 함수는 자동으로 Future를 반환합니다.
  • await는 Future가 완료될 때까지 현재 async 함수의 실행을 잠시 멈춥니다.

부연 설명

오류 처리

  • try/catch로 비동기 오류를 처리합니다.
  • UI에서는 로딩, 성공, 실패 상태를 명확히 나눕니다.
  • finally는 성공과 실패와 관계없이 정리 작업을 실행할 때 사용합니다.

깊게 이해하기

Future는 지금 당장 값이 없지만 나중에 성공 또는 실패로 끝나는 작업입니다. UI에서는 Future의 진행 상태를 로딩, 성공, 실패로 나누어 다루는 습관이 중요합니다.

async/await는 비동기를 동기 코드처럼 보이게 해 주지만, 실제로는 이벤트 루프 위에서 동작합니다. 오래 걸리는 작업이 여러 개라면 순차 실행과 병렬 실행의 차이도 고려해야 합니다.

상세 예제

API 호출을 안전하게 감싸고 UI 상태로 바꾸는 예제입니다.

class LessonService {
  Future<List<Lesson>> loadLessons() async {
    try {
      final response = await api.get('/lessons');
      return response.map(Lesson.fromJson).toList();
    } catch (error) {
      throw Exception('강의 목록을 불러오지 못했습니다: $error');
    }
  }
}

Future<void> refresh() async {
  setState(() => isLoading = true);
  try {
    lessons = await service.loadLessons();
  } finally {
    if (mounted) setState(() => isLoading = false);
  }
}

실무에서 주의할 점

  • 비동기 후 setState를 호출할 때 mounted 여부를 확인하세요.
  • 서로 독립적인 Future는 Future.wait로 병렬 처리할 수 있습니다.
  • 오류를 삼키지 말고 UI가 표시할 수 있는 형태로 변환하세요.

실습 체크리스트

Future 반환 함수 작성await 사용try/catch 처리