중급

Future와 async/await

네트워크 요청과 파일 작업처럼 나중에 끝나는 작업을 다룹니다.

핵심 개념

Future와 async/await 주요 항목

Future의 의미

Future는 지금 당장 값이 없지만 나중에 성공하거나 실패하는 작업입니다.

언제 쓰나: Flutter 앱에서는 API 호출, 로컬 저장소 읽기, 파일 작업에서 자주 사용합니다.

Flutter에서: async/await는 비동기 코드를 순서대로 읽히게 만들어 줍니다.

Card(
  child: Padding(
    padding: const EdgeInsets.all(16),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: const [
        Text('Future의 의미', style: TextStyle(fontWeight: FontWeight.bold)),
        SizedBox(height: 8),
        Text('Future는 지금 당장 값이 없지만 나중에 성공하거나 실패하는 작업입니다.'),
      ],
    ),
  ),
)

UI와 연결

비동기 작업은 로딩, 성공, 실패 상태를 나누어 화면에 표현해야 합니다.

언제 쓰나: FutureBuilder는 Future의 상태에 따라 UI를 분기할 때 사용할 수 있습니다.

Flutter에서: 비동기 작업 후 setState를 호출할 때는 위젯이 아직 mounted 상태인지 확인해야 합니다.

abstract class LessonRepository {
  Future<List<String>> findTitles();
}

class LessonController {
  LessonController(this.repository);

  final LessonRepository repository;
}

상세 설명

더 알아보기

비동기 결과를 화면에 붙일 때는 데이터보다 상태를 먼저 설계합니다. isLoading, data, error를 분리하면 버튼 재시도, 빈 화면, 오류 문구를 안정적으로 처리할 수 있습니다.

여러 요청이 서로 의존하지 않는다면 순서대로 await하기보다 Future.wait를 고려할 수 있습니다. 반대로 앞 요청 결과가 뒤 요청의 입력이면 순차 흐름이 더 명확합니다.

코드

예제

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 반환 함수 작성try/catch 처리로딩/오류 UI 만들기
  • 출처세부 기준과 최신 변경 사항을 확인할 수 있습니다.
  • Flutter API Reference클래스, 메서드, 생성자 세부 정의를 확인합니다.
  • Dart languageDart 문법 자체가 궁금할 때 함께 봅니다.