Flutter로 앱 개발 중, 비동기식에 Future의 WhenComplete와 Then의 차이점이 문득 궁금해졌다. 그리고 catchError는 어떻게 작동할까?
바쁜 사람을 위해 결론!
- Then과 whenComplete는 역할이 다르다.
- Then은 Error가 없다면 결괏값을 value로 받아서 실행한다. 하지만, Error가 Return 되면 출력이 되지 않는다.
- WhenComplete는 Future가 끝나면 무조건 실행된다.(Error 발생 유무에 관계가 없다.)
- catchError는 Error가 Return이 될 때 작동하며, Error가 Return 되더라도 catchError가 있다면 Then이 실행된다.
1. Then, whenComplete, catchError,는 try, catch, final로 생각하면 간단하다.
일단 구글에 'flutter future then whencomplete' 검색하니 stackoverflow에 나온다.
여기 첫 번째 답변에 따르면,
''.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
사실 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는 final이라고 생각하면 된다.
오류, 지적사항 그리고 궁금한 것은 댓글 부탁드립니다.
21.07.18 수정
'Study > Dart,Flutter' 카테고리의 다른 글
6. Flutter의 Widget과 State 그리고 StatelessWidget과 StatefulWidget (0) | 2021.08.19 |
---|---|
5. Dart Flutter, 플러터의 비동기의 Return, then과 try catch (0) | 2021.07.30 |
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 |