Dart Flutter, Future의 whenComplete, then 그리고 catchError의 고찰

김은상·2022년 8월 4일
0
post-thumbnail

바쁜 사람을 위해 결론!
1. Then과 whenComplete는 역할이 다르다.
2. Then은 Error가 없다면 결괏값을 value로 받아서 실행한다. 하지만, Error가 Return 되면 출력이 되지 않는다.
3. WhenComplete는 Future가 끝나면 무조건 실행된다.(Error 발생 유무에 관계가 없다.)
4. catchError는 Error가 Return이 될 때 작동하며, Error가 Return 되더라도 catchError가 있다면 Then이 실행된다.

1.

Then, whenComplete, catchError,는 try, catch, final로 생각하면 간단하다.
일단 구글에 'flutter future then whencomplete' 검색하니 stackoverflow에 나온다.
Difference between .then() and .whenCompleted() methods when working with Futures?

여기 첫 번째 답변에 따르면,

''.whenComplete will fire a function either when the Future completes with an error or not, instead .then will fire a function after the Future completes without an error.''

whencomplete는 future가 에러 가뜨 건 안 뜨건 작동이 되고, then은 에러 없이 작동이 끝나야지 작동한다는 뜻이다.
음, 좋아 간단한데 밑에 이상한 답글이 또 있다.

Not actually... if you put then after catchError , then is called because catchError returns a completely new Future, indeed if were to return an error inside catchError .then won't be fired, in asynchronous code your code would be something like this: gist.github.com/Hexer10/87a6f38616f74321c85f2f91a5450d4e – Mattia May 11 '20 at 18:09 User Mattia

사실 catchError 뒤에다가 then을 쓴다면 then이 호출이 되는데, catchError가 완전한 Future을 Return 시키기 때문이다.
indeed if were to return an error inside catchError. then won't be fired,->이건 무슨 뜻일까...

  try {
    await someFuture();
  } catch (e) {
    print("called when there is an error catches error: $e");
    try {
      print("called with value = null");
    } finally {
      print("called when future completes");
    }
  }

하고 링크에 들어가면 이러한 코드가 있다.
아유 헛갈리는데 그냥 직접 해 보자.


간단하게 가자.


먼저 whenComplete와 then의 차이점을 보자.

  Future futureAsync() async {
    return Future.delayed(new Duration(seconds: 3));
  }
  
  
  await futureAsync().then((value) {
  	print("Then");
    }).whenComplete(() {
      print("WhenComplete");
    });

코드만 봐도 다른 점을 찾기 쉬운 게, then은 value를 가져오지만, whenComplete는 value가 없다.
실행하면

I/flutter (13166): Then
I/flutter (13166): WhenComplete

둘 다 출력이 된다. 그러면 에러가 발생했을 때는 어떻게 될까? futureAsync의 함수를 수정해서 실행시켜보자

 Future futureAsync() async {
     return Future.error("error");
 }
 await futureAsync().then((value) {
 	print("Then");
   }).whenComplete(() {
     print("WhenComplete");
   });
   
I/flutter (13166): WhenComplete
E/flutter (13166): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)] Unhandled Exception: error
E/flutter (13166):

Then이 실행되지 않는다! WhenComplete는 실행이 된 후 Error를 보여주게 된다!

그렇다면 이번엔 catchError를 실행해 보자.

  Future futureAsync() async {
      return Future.error("error");
  }
  
  await futureAsync().catchError((onError) {
    print("ERROR : $onError");
  }).then((value) {
    print("Then");
  }).whenComplete(() {
    print("whenComplete");
  });
  
ERROR : Set error
Then
whenComplete

StackOverflow말대로 catchError가 있다면 Then이 실행된다!

그렇다면 마지막으로 Error가 아닌 경우에 catchError를 적어놓은 경우에는 어떻게 될까?

  Future futureAsync() async {
  	return Future.delayed(new Duration(seconds: 3));
  }
  
await futureAsync().catchError((onError) {
      print(onError);
    }).then((value) {
      print("Then");
    }).whenComplete(() {
      print("WhenComplete");
    });
    
I/flutter (13166): Then
I/flutter (13166): WhenComplete

결론

Then과 whenComplete는 역할이 다르다.
Then은 Error가 없다면 결괏값을 value로 받아서 실행한다. 하지만, Error가 Return 되면 출력이 되지 않는다.
WhenComplete는 Future가 끝나면 무조건 실행된다.(Error 발생 유무에 관계가 없다.)
catchError는 Error가 Return이 될 때 작동하며, Error가 Return 되더라도 catchError가 있다면 Then이 실행된다.

간단하게 Then은 try라고 생각하면 되고 whenComplete는 finally라고 생각하면 된다.

출처 : https://pcseob.tistory.com/3

profile
Flutter 시작

0개의 댓글