이전 포스팅한 내용은 Dart에서 비동기가 어떻게 작동하고 어떻게 제어하는지 포스팅을 했었다. 이번에는 비동기 함수의 결괏값을 어떻게 받아오는지 알아보자.
결론
- Dart의 비동기함수의 예외처리는 두 가지 방법이 있다.
- 첫 번째는, try catch finally로 한다. try를 진행하고 에러가 발생하면 catch가 작동하며 try 혹은 catch작동 이후 finally가 실행된다.
- 두 번째는, then catchError, whenComplete를 사용한다. 작동은 try가 then, catch가 catchError, finally가 whenComplete라고 생각하면 된다.
- 둘 중에 무엇이 좋다고 딱 잘라서 말을 할 순 없다. 하지만 잘 짠 코드에서는 코드의 가독성도 중요하므로 상황에 맞게 사용하도록 하자.
앞에 포스팅한 것을 안 읽은 사람들을 위해 다시 링크를 올리겠다.
https://dart.dev/codelabs/async-await
이전 포스팅의 코드를 가져와서 이어서 설명을 하겠다.
void main() {
getCoffee();
}
getCoffee() async {
String menu = await todayCoffee();
print("Today Coffee is $menu");
}
Future<String> todayCoffee() {
return Future.delayed(Duration(seconds: 1), () => "Latte");
}
여기서 변수 menu가 비동기함수가 끝나면 결괏값을 받아오는 것을 알 수 있다. 물론 이렇게 모든 코딩이 간단하면 얼마나 좋을까? 하지만 비동기 함수에서 오류가 발생하는 경우를 생각해야 한다.
잠시 예외처리 대해서 생각을 해 보자. 예외처리는 굉장히 중요하다. 물론 코딩할 때는 예외처리를 굳이 적용시키지 않아도 IDE에서 어디서 오류가 났는지 잘 보여준다. 하지만 어플리케이션을 사용하는 사용자 입장에서 오류가 발생했는데 예외처리가 되어있지 않다면, 애플리케이션이 픽 하고 꺼져버리거나 제어가 되지 않아 강제로 꺼야 하는 상황히 발생한다.
만약 예외처리가 되어있다면, 애플리케이션은 꺼지지 않고 "오류가 났습니다. 앱을 재실행시켜주십시오"라고 띄우던지 에러코드를 띄워준다면 사용자들은 조금 더 나은 경험을 할 것이다(UX).
그렇다면 비동기식 함수에 예외처리는 어떻게 할까? 많이 알고 있는 try catch를 사용하면 될까? 맞다. try catch finally을 사용하면 아주 깔끔하게 처리할 수 있다. 그리고 try catch finally 이외에 then, catchError 그리고 whenComplete를 이용하면 동일한 성능을 낼 수 있다.
우선 try catch부터 알아보자.
void main() {
getCoffee();
}
void getCoffee() async {
try {
var menu = await todayCoffee();
print('Today Coffee is $menu');
} catch (e) {
print('Catch Error : $e');
} finally {
print('Final');
}
try {
var menu = await spillCoffee();
print('Today Coffee is $menu');
} catch (e) {
print('Catch Error : $e');
} finally {
print('Final');
}
}
Future<String> todayCoffee() {
return Future.delayed(Duration(seconds: 1), () => 'Latte');
}
Future<String> spillCoffee() {
return Future.error('Spill Coffee!');
}
//출력
//Today Coffee is Latte
//Final
//Catch Error : Spill Coffee!
//Final
아시다시피 try의 내용을 실행을 하고 실행하다가 에러가 발생하는 경우에는 catch를 실행, finally를 실행시킨다.
이렇게 예외 처리하는데 try catch finally를 사용하는 게 가장 보편적이고 권장되고 있다.
이번에는 then, catchError 그리고 whenComplete에 대해서 알아보자.
void main() {
getCoffee();
}
void getCoffee() async {
await todayCoffee()
.then((value) => print('Today Coffee is $value'))
.catchError((e, stackTrace) {
print('Catch Error : $e');
}).whenComplete(() => print('whenComplete'));
//Then을 통해서 값을 Return시킬 수 있고, 아래 함수처럼 사용할 수 있다.
//=>는 람다식으로 간단하게 return이라고 생각하면 된다.
await spillCoffee()
.then((value) => print('Today Coffee is $value'))
.catchError((e, stackTrace) {
print('Catch Error : $e');
}).whenComplete(() => print('whenComplete'));
}
Future<String> todayCoffee() {
return Future.delayed(Duration(seconds: 1), () => 'Latte');
}
Future<String> spillCoffee() {
return Future.error('Spill Coffee!');
}
//출력
//Today Coffee is Latte
//whenComplete
//Catch Error : Spill Coffee!
//whenComplete
코드를 천천히 읽어보기 바란다. 무엇이 더 나은 코드다 무엇이 더 나은 작동이다 라고 말하기는 모호하지만, 확실히 위의 try catch finally보다 직관적이라고 하기는 힘들어 보인다.
결론
- Dart의 비동기 함수의 예외처리는 두 가지 방법이 있다.
- 첫 번째는, try catch finally로 한다. try를 진행하고 에러가 발생하면 catch가 작동하며 try 혹은 catch작동 이후 finally가 실행된다.
- 두 번째는, then catchError, whenComplete를 사용한다. 작동은 try가 then, catch가 catchError, finally가 whenComplete라고 생각하면 된다.
- 둘 중에 무엇이 좋다고 할 순 없다. 하지만 잘 짠 코드에서는 코드의 가독성도 중요하므로 상황에 맞게 사용하도록 하자.
오류, 지적사항 그리고 궁금한 것은 댓글 부탁드립니다.
'Study > Dart,Flutter' 카테고리의 다른 글
7. StatefulWidget의 LifeCycle(생명주기) 그리고 setState (0) | 2021.08.30 |
---|---|
6. Flutter의 Widget과 State 그리고 StatelessWidget과 StatefulWidget (0) | 2021.08.19 |
4. Dart Flutter, 플러터의 비동기식 Future, await 그리고 async (0) | 2021.07.28 |
3. Dart Flutter, Asynchronous, Isolates와 Event Loop 에 관한 고찰 (0) | 2021.07.23 |
2. 플러터 Navigator와 onGenerateRoute그리고 popUntil 의 고찰 (0) | 2021.05.15 |