포스팅이 점점 더 기초적으로 가지만, 짚고 넘어가야 할 것 같아서 작성하게 되었다.
앞서 Dart의 비동기의 작동방식을 살펴보았다. 그러면 어떻게 사용하는지 살펴보자.
바쁜 사람을 위한 빠른 결론!
- Dart Flutter에서 비동기식을 사용할 때 Future, async, await를 사용한다.
- 함수 이름 앞 Future은 반환을 나타낸다. 가독성을 위해 적는것을 추천하지만, 생략해도 무방하다.
- await를 사용하기 위해서는 반드시 async가 적혀있어야한다.
- await를 사용하면 비동기 함수가 끝날때까지 기다리며, await를 사용하지않으면 기다리지않는다.
- 비동기함수가 끝났음을 알리고싶다면 Callback함수를 이용하여 알릴 수 있다.
직전 포스팅을 안 읽은 사람들을 위해 Dart 공식홈페이지 링크를 다시 올리겠다.
https://dart.dev/codelabs/async-await
Flutter에서 비동기식을 왜 사용할까?
여러이유가 있겠지만 가장 큰 이유는 외부DB에 생성,읽기,수정,삭제(CRUD)하는데 있다 . 외부에서 데이터를 조작하는동안 메인에서는 다른 작업을 할 수 있다. 그래서 데이터를 가져오는동안 메인에서 다른작업 수행하고, 비동기식으로 불러온 데이터가 준비완료 된다면 사용하는 방식이 되어야 한다.
그러면 비동기를 사용한 코드를 보자.
위의 Dart 공식홈페이지를 보거나 구글링을 조금만 해 보면 비동기식을 알 수 있겠지만, 처음부터 천천히 다져보자.
void main() {
getCoffee();
}
getCoffee() async {
String menu = await todayCoffee();
print("Today Coffee is $menu");
}
//쌍따옴표 사이에 $는 변수를 String으로 출력하기 위한 것이다.
//함수 속 변수를 출력하려면 ${Starbucks.coffee} 처럼 사용해야한다.
Future<String> todayCoffee() {
return Future.delayed(Duration(seconds: 1), () => "Latte");
}
//=>의 표현은 람다(Lambda)식 이라고 읽는다.
//간단하게 return처럼 사용하면 되며, 자세한내용은 아래링크 참고
//https://khj93.tistory.com/entry/JAVA-%EB%9E%8C%EB%8B%A4%EC%8B%9DRambda%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B4%EA%B3%A0-%EC%82%AC%EC%9A%A9%EB%B2%95
//출력
//(1초 후)
//Today Coffee is Latte
최대한 쉽게 작성했지만, 보자마자 머리아플 수 있으니 차근차근 설명하겠다.
getCoffee에서 매개변수(parameter)를 받는 ()와 {}사이에 async가 적혀져있다. 이 async는 반드시 await를 사용하기위해서 필요하다. async를 붙이지 않으면 await를 사용 할 수 없다.
그렇다면 await는 무엇일까? 말그대로 기다리는거다. 비동기 함수가 끝날 때까지 기다린다. 기다린 후 그 이후의 작업을 진행하게 된다. 그래서 출력값은 딜레이 1초 후 Today Coffee is Latte가 되는 것이다. await는 반환값이 Future인 함수 앞에 사용한다.(물론 아닌거에도 붙일 수 있긴하고, async가 있는데 await를 안 써도 된다.)
Future<String>은 String으로 반환을 하는데, 비동기로 반환을 한다. 라고 이해하면 좋다. 물론 Future<String>의 부분은 생략이 가능하며, Future 만 사용해도 자동으로 Future<dynamic>으로 인식한다.
몇몇 분들은 'await해서 기다릴거면 비동기식으로 사용한 의미가 없지않나?' 라고 생각 할 수 있다.
void main() {
getLunch();
}
todayLunch() {
return Future.delayed(Duration(seconds: 1), () {
print("Pasta");
});
// () {print("Pasta");}는 ()=>print("Pasta")로 가능하다.
}
getLunch() {
print("Today Lunch");
todayLunch();
print("Still Wait");
}
//출력
//Today Lunch
//Still Wait
//Pasta
비동기식 처리를 기다리지 않길 원하면 await를 붙이지 않으면 된다.
'그러면 비동기식으로 처리하고 끝났으면 main에 알리고싶으면 어떻게하지?' 라고도 생각할 수 있다. 전역변수를 사용해도 되지만, 개인적으로 Callback함수를 사용하는게 더 낫다고 생각한다.
void main() {
todayDinner();
}
todayDinner() {
print("Today Dinner");
getDinner(menuCallback);
print("Still Wait...");
}
getDinner(Function callback) {
return Future.delayed(Duration(seconds: 1), () {
String menu = "Steak";
callback(menu);
});
}
menuCallback(String menu) => print("Today Dinner is $menu");
//Callback함수는
//1. 다른 함수의 인자로써 이용되는 함수.
//2. 어떤 이벤트에 의해 호출되어지는 함수.
//라고 할 수 있다. 더 자세한건 아래 링크 참고
//https://stackoverflow.com/questions/824234/what-is-a-callback-function
//출력
//Today Dinner
//Still Wait...
//Today Dinner is Steak
그렇다면 어디에서 await를 쓰고 어디에서 await를 쓰지않으면 될까?
앱을 키는순간 중요한 데이터들은 await해서 데이터를 불러와야 할 것이다. 하지만 상대적으로 중요도가 떨어지는 데이터들은 await를 사용하지 않고 백그라운드에서 작업을 진행해도 무방할 것이다.
예를들어 중고장터같은 앱을 제작한다고 했을 때, 사용자의 정보와 바로 보여야하는 메인화면에 관련된 데이터는 await를 써야 할 것이다.
하지만 메인화면에 바로 보여지지 않는 공지사항같은 것은 await를 사용하지 않고, 사용자가 불러오기 전 공지사항을 실행한다면 로딩창을 띄워주면 될 것이다.
결론
- Dart에서 비동기식을 사용할 때 Future, async, await를 사용한다.
- 함수 이름 앞 Future은 반환을 나타낸다. 가독성을 위해 적는것을 추천하지만, 생략해도 무방하다.
- await를 사용하기 위해서는 반드시 async가 적혀있어야한다.
- await를 사용하면 비동기 함수가 끝날때까지 기다리며, await를 사용하지않으면 기다리지않는다.
- 비동기함수가 끝났음을 알리고싶다면 Callback함수를 이용하여 알릴 수 있다.
오류, 지적사항 그리고 궁금한 것은 댓글 이용 부탁드립니다.
'Study > Dart,Flutter' 카테고리의 다른 글
6. Flutter의 Widget과 State 그리고 StatelessWidget과 StatefulWidget (0) | 2021.08.19 |
---|---|
5. Dart Flutter, 플러터의 비동기의 Return, then과 try catch (0) | 2021.07.30 |
3. Dart Flutter, Asynchronous, Isolates와 Event Loop 에 관한 고찰 (0) | 2021.07.23 |
2. 플러터 Navigator와 onGenerateRoute그리고 popUntil 의 고찰 (0) | 2021.05.15 |
1. Dart Flutter, Future의 whenComplete, then 그리고 catchError의 고찰(수정) (0) | 2021.05.12 |