Study/Dart,Flutter

5. Dart Flutter, 플러터의 비동기의 Return, then과 try catch

코딩 잘 할거얌:) 2021. 7. 30. 23:11
반응형

이전 포스팅한 내용은 Dart에서 비동기가 어떻게 작동하고 어떻게 제어하는지 포스팅을 했었다. 이번에는 비동기 함수의 결괏값을 어떻게 받아오는지 알아보자.

렛츠고!


결론

  1. Dart의 비동기함수의 예외처리는 두 가지 방법이 있다. 
  2. 첫 번째는, try catch finally로 한다. try를 진행하고 에러가 발생하면 catch가 작동하며 try 혹은 catch작동 이후 finally가 실행된다.
  3. 두 번째는, then catchError, whenComplete를 사용한다. 작동은 try가 then, catch가 catchError, finally가 whenComplete라고 생각하면 된다.
  4. 둘 중에 무엇이 좋다고 딱 잘라서 말을 할 순 없다. 하지만 잘 짠 코드에서는 코드의 가독성도 중요하므로 상황에 맞게 사용하도록 하자.

앞에 포스팅한 것을 안 읽은 사람들을 위해 다시 링크를 올리겠다.

https://dart.dev/codelabs/async-await

 

Asynchronous programming: futures, async, await

Learn about and practice writing asynchronous code in DartPad!

dart.dev

이전 포스팅의 코드를 가져와서 이어서 설명을 하겠다.

  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보다 직관적이라고 하기는 힘들어 보인다.


결론

  1. Dart의 비동기 함수의 예외처리는 두 가지 방법이 있다.
  2. 첫 번째는, try catch finally로 한다. try를 진행하고 에러가 발생하면 catch가 작동하며 try 혹은 catch작동 이후 finally가 실행된다.
  3. 두 번째는, then catchError, whenComplete를 사용한다. 작동은 try가 then, catch가 catchError, finally가 whenComplete라고 생각하면 된다.
  4. 둘 중에 무엇이 좋다고 할 순 없다. 하지만 잘 짠 코드에서는 코드의 가독성도 중요하므로 상황에 맞게 사용하도록 하자.

오류, 지적사항 그리고 궁금한 것은 댓글 부탁드립니다.

728x90