🚧 해당 게시글은 FastCampus의 15개 프로젝트로 실무까지 끝내는 Dart & Flutter 앱 개발 강의를 기반으로 작성되었습니다.
강의 링크 👉 https://fastcampus.co.kr/dev_online_dartflutter
비동기란 코드가 동시다발적으로 진행되는 형태로, 순차적 진행을 보장할 수 없습니다.
사용되는 주요 개념으로 Future
와 Stream
이 있습니다.
Future
는 단일 비동기 작업의 결과를 나타내는 데, Stream
은 여러 값 또는 이벤트의 시퀀스를 나타내는 데 사용됩니다.
1회만 응답을 돌려받는 경우 사용되는 비동기 객체
ex) 서버에 응답을 받는 경우
Future
를 이용하여 비동기 작업을 시작하면 결과는 Future
객체에 저장됩니다.
문제없이 진행된 후의 결과를 받는 then
함수 예외가 발생할 경우를 대비할 수 있는 catchError
함수 등으로 각 결과들에 대한 처리를 정의할 수 있습니다.
Future<int> fetchData() async {
await Future.delayed(Duration(seconds: 5));
return 5; // 비동기 작업 결과
}
void main() {
fetchData().then((result) {
print('비동기 작업 결과: $result');
}).catchError((error) {
print('에러 발생: $error');
});
}
비동기 함수임을 정의하는 키워드입니다.
정의된 함수는 비동기 작업을 수행할 수 있습니다.
Future<리턴타입> 함수명() async {
// 비동기 작업을 수행하는 코드
}
// 리턴 타입이 없는 void의 경우 아래와 같이 정의가 가능합니다
void 함수명() async {
// 비동기 작업을 수행하는 코드
}
비동기 함수 내에서 사용되는 키워드입니다.
작업이 완료될 때까지 함수의 실행을 중단하고 대기합니다.
Future<void> fetchData() async {
var result = await AsyncFunction();
// 이후는 AsyncFunction()이 완료된 후 실행
}
여러 비동기 작업을 동시에 실행하려면 Future.wait
메서드를 사용하여 구현할 수 있습니다.
여러 Future
객체를 동시에 실행하고 모든 Future
가 완료될 때까지 대기 후, 결과를 한꺼번에 반환하는 메서드입니다.
Future<String> someAsyncFunction1() async {
await Future.delayed(Duration(seconds: 1));
return 'Function1';
}
Future<String> someAsyncFunction2() async {
await Future.delayed(Duration(seconds: 5));
return 'Function2';
}
void fetchMultipleData() async {
final results = await Future.wait([someAsyncFunction1(), someAsyncFunction2()]);
// results에 각 작업의 결과가 저장됨
print('모든 작업 완료: $results');
}
지속적으로 응답을 돌려받는 경우 혹은 이벤트의 시퀀스 처리에 사용되는 비동기 객체
ex) 타이머와 같이 지속적으로 일정주기로 반복해야 하는 경우
Stream
은 스트림을 생성하고 각 값 또는 이벤트가 도착할 때마다 처리할 수 있기 때문에 실시간 이벤트 처리, 스트리밍 데이터 및 대용량 데이터 처리에 유용합니다.
Stream<int> countStream() async* {
for (int i = 0; i <= 10; i++) {
await Future.delayed(Duration(seconds: 1));
yield i; // 스트림에 값 전달
}
}
void getStream() async {
await for (int count in countStream()) {
print('스트림 값: $count');
}
}
스트림을 생성하고 async와 같이 값을 하나씩 전달할 수 있는 제너레이터 비동기 함수임을 정의할 때 사용되는 키워드입니다.
Stream<리턴타입> 함수명() async* {
// 비동기 작업 코드
}
async* 함수 내에서 스트림으로 값을 전달할 때 사용되는 키워드입니다.
return 과 같은 역할을 한다고 볼 수 있습니다.
프로그램이 진행 중일 때, 의도하거나 의도치 않은 상황에서 오류가 발생했을 때 대처하기 위한 기능입니다.
프로그램 안정성 유지와 오류 관리에 중요한 역할을 하며, 적절한 처리를 통해 오류를 대처하고 필요에 따라서 사용자에게 오류 메시지를 제공할 수 있습니다.
가장 자주 쓰이는 기본적인 예외처리문
try
블록 내에서 예외가 발생할 수 있는 코드를 감싸고, catch
블록에서 예외를 처리하며 해당 catch
는 타입을 가리지 않습니다.
try {
// 예외가 발생할 수 있는 코드
} catch (e) {
print("예외가 발생했습니다: $e");
}
특정 에러 타입을 잡을 때 사용되는 예외처리문
중복으로 사용 가능하기에 에러 타입에 따라 각기 다른 처리를 할 수 있습니다.
try {
// 예외가 발생할 수 있는 코드
} on Exception1 catch (e) {
// Exception1 유형의 예외 처리
} on Exception2 catch (e) {
// Exception2 유형의 예외 처리
} catch (e) {
// 다른 모든 예외 유형을 처리
}
try - catch와 함께 사용하는 예외처리문
예외가 발생했던 하지 않았던, try - catch 이후 반드시 코드를 실행할 때 사용합니다.
try {
// 예외가 발생할 수 있는 코드
} catch (e) {
// 예외 처리
} finally {
// 항상 실행되는 코드
}
예외(에러)를 만들어서 던지는 키워드
사용자 정의 에러를 발생시킬 수 있으며, 잘 사용한다면 코드가 의도하지 않은 방향으로 진행되는 것을 방지할 수 있습니다.
void myFunction() {
// 예외 발생
throw Exception('사용자 정의 예외');
}
이미 catch한 에러를 재발생 시키는 작업을 하는 키워드.
try {
// 예외가 발생할 수 있는 코드
} catch (e) {
// 예외 처리
rethrow; // 현재 예외를 다시 발생
}