조금 매운맛 8 Future, async, awite 이해하기
예로 햄버거를 주문할 때,
햄버거를 주문함
1. 결제 후 영수증을 받음
2. 전광판을 보면서 영수증에 적힌 내 번호를 찾음
3. 번호가 뜨면 영수증을 교환해서 햄버거를 찾음
4. 맛있게 먹음
2번에서 영수증은 중요한 것이 아님.
영수증과 영수증에 적힌 번호는 3번(미래)에서 햄버거를 받겠다는 일종의 약속.
Future은 아직 받지 않은 햄버거처럼 실재하지 않는 상태
후에 영수증을 교환해서 햄버거를 찾는 것처럼 미래에 구체적인 것으로 바뀐다는 개념
Future
- 미래에 String, int, image 등 어떤 것이 결과물로 나타나서 객체로 반환되는 것
- 일종의 약속
- 잠시 후에 결과를 확인 할 수 있는 실재적인 사물이 '될' 것
- 미개봉 박스와 같음 = 개봉 전 박스 안에 무엇이 있는지 모르지만 개봉하면 String이 들어 있는 것을 알 수 있는 것과 같음

- Generic 제네릭처럼 타입을 지정해줄 수 있음
짜장면집 예
짜장면 8개, 짬뽕 1개, 볶음밥 1개 주문
1. 짜장면만 먼저 만들어서 손님상에 먼저 내보낸 후, 짬뽕 만들고 내보내고, 볶음밥 만들고 내보내기
> 한번에 1가지만 집중해서 함 = Synchronous 방식
2. 짜장면 볶으면서 + 짬뽕 면 삶고 + 설거지도 함
> 한번에 여러가지 일을 함 = Asynchronous 방식
awaite
- 작업이 끝날 때까지 기다리기
Dart를 이용해서 Future, async, awite 간단실습
- 이전의 로그인 리팩토링 프로젝트 그대로 이용
- test 폴더의 widget_test.dart 이용
//widget_test.dart
import 'dart:io'; //소켓이나 http 통신이 필요할때 쓰는 라이브러리
void main(){
showData();
}
void showData(){
startTask();
accessData();
fetchData();
}
void startTask(){
String info1 = '요청수행 시작';
print(info1);
}
void accessData(){
String info2 = '데이터에 접속중';
print(info2);
}
void fetchData(){
String info3 = '잔액은 8,500만원입니다';
print(info3);
}
딜레이 임의로 줌
void accessData(){
Duration time = Duration(seconds: 3); //지연시간
sleep(time); //time에 담긴 시간만큼 멈춤
String info2 = '데이터에 접속중';
print(info2);
> 코드들이 Synchronous 하게 실행된다.
= 실행에 시간이 걸리던 안 걸리든 순차가 되면 무조건 실행됨

void accessData(){
Duration time = Duration(seconds: 1); //지연시간
if(time.inSeconds > 2) {
sleep(time); //time에 담긴 시간만큼 멈춤
String info2 = '데이터에 처리 완료';
print(info2);
}else{
String info2 = '데이터를 가져왔습니다';
print(info2);
}
}

void accessData(){ // 1)
Duration time = Duration(seconds: 3); // 3)
if(time.inSeconds > 2) {
//sleep(time);
Future.delayed(time, (){ // 2)
String info2 = '데이터에 처리 완료'; // 5)
print(info2); //6)
});
}else{
String info2 = '데이터를 가져왔습니다';
print(info2);
}
}
void fetchData(){ // 4)
(* 문제점
위의 Future 코드를 안드로이드 스튜디오에서 실행시 마지막에 떠야할 '데이터에 처리 완료' 가 뜨지 않음.
DartPad에서는 문제 없이 실행하는 것으로 보아 아마 안드스튜디오 문제일듯.)
> 코드 설명
1) accessData가 실행되는 과정에서
2) Future.delayed를 만나면
3) 3초동안 실행이 중단되고
4) 다음 코드(=fetchData)로 넘어가서 '잔액~' 출력
5) 3초가 지난 후, info2에 변수값 할당
- Future<void> 함수는 끝이 언제날지 지정해 줄 수 있음.
** 공부 필요
-전 단계가 실행되고 이후에 다음 단계가 실행되어야 하는 경우
void main(){
showData();
}
void showData(){
startTask();
String account = accessData();
fetchData(account);
}
void startTask(){
String info1 = '요청수행 시작';
print(info1);
}
String accessData(){
String account='';
Duration time = Duration(seconds: 3); //지연시간
if(time.inSeconds > 2) {
//sleep(time); //time에 담긴 시간만큼 멈춤
Future.delayed(time, (){
account = '8,500만원';
print(account);
});
}else{
String info2 = '데이터를 가져왔습니다';
print(info2);
}
return account;
}
void fetchData(String account){
String info3 = '잔액은 $account 입니다.';
print(info3);
}
> 실행하면 밑에 사진과 같이 여전히 async 방식으로 처리해서 그럼
fetch 함수가 먼저 실행된 후 access 함수가 실행됨.
근데 fetch 함수가 access 함수의 결과값을 받아야하는데 먼저 실행되는 바람에 이사단이 난거임

강제로 기다리게해서 fetch 함수로 access 함수의 결과값이 넘어가도록 만들어보자
1. String access 함수 바꾸기
Future<String> accessData()
2. future.delyed 함수가 실행될때까지 기다려야함으로 async modify 붙여주기
Future<String> accessData() async{
* 반드시 async는 { 중괄호 앞에 위치해야 함
async 추가 하면 await 키워드 사용 가능
3. await 붙이기
await Future.delayed(time, (){
> future.delayed 실행이 끝날때까지 기다리란 뜻
4. 복붙
void showData() async{
5. await 붙여주기
String account = await accessData();
> accessData가 끝날때까지 기다리라는 뜻
실행해보면 우리가 원하는 결과값이 나옴

전체코드
void main(){
showData();
}
void showData() async{
startTask();
String account = await accessData();
fetchData(account);
}
void startTask(){
String info1 = '요청수행 시작';
print(info1);
}
Future<String> accessData() async{
String account='';
Duration time = Duration(seconds: 3); //지연시간
if(time.inSeconds > 2) {
//sleep(time); //time에 담긴 시간만큼 멈춤
await Future.delayed(time, (){
account = '8,500만원';
print(account);
});
}else{
String info2 = '데이터를 가져왔습니다';
print(info2);
}
return account;
}
void fetchData(String account){
String info3 = '잔액은 $account 입니다.';
print(info3);
}
마지막 정리
1. Future 클래스는 비동기 작업을 할 때 사용
2. Future 는 일정 소요시간 후에 실제 데이터나 에러를 반환
3. async 클래스는 await 메소드를 가지고 있음
- await 선언된 메서드는 응답이 처리될 때까지 대기
~ 앱 실습은 스킵 ~
조금 매운맛 9 AndroidX 마이그레이션(migration)
Migration 마이스레이션 : 기존의 운영 환경 A에서 더 나은 운영 환경 B로 옮기는 과정
AndroidX : 기존에 사용하던 여러 라이브러리를 1개로 통합 한 것
- Android studio 3.2 이상 / Compile SDK 28.0 이상 버전부터 사용할 수 있음
- 오래된 프로젝트를 다운 받았을 때 마이그레이션 하는 법
1) 먼저 해당 프로젝트가 AndroidX 사용했는지 확인
: Project 탭 - android - gradle.properties

오래 된 경우 다음 코드만 있음
org.gradle.jvmargs=-Xmx1536M
그럴경우 아래 코드 복붙
android.useAndroidX=true // androidX 사용하겠다는 의미
android.enableJetifier=true // androidX 프로젝트에서 사용할 수 있도록 Third-party 라이브러리 자동 마이그레이션
2) Project 탭 - android - build.gradle 띄우기

File - Open - 프로젝트 내 android 선택해서 새 창으로 띄우기

> gradle sync 과정이 자동으로 실행됨
> 우측 하단에 plugIn Update 팝업창 뜨는데 그대로 업데이트
> 완료되면 build 창에 'CONFIGURE SUCCESSFUL in 0s' 라고 뜸
3) Refactor - Migrate to AndroidX

> Migrate 버튼 누르면 왼쪽 하단에 'Do Refator' 클릭
끝~
Kotlin suport 사용 / AndroidX 사용 안 하는 마이그레이션 버전은 생략
필요하다면 후에 다음 영상 5:30~ 참조
https://youtu.be/h00EuSl0qBw?t=330
'공부 > Flutter' 카테고리의 다른 글
| Flutter 스터디 21 Flutter 2.0과 Null safety 널 세이프티 (0) | 2023.02.13 |
|---|---|
| Flutter 스터디 20 반복문 loop와 추첨 프로그램, Future-async 심화학습 (1) | 2023.02.13 |
| Flutter 스터디 18 final 변수와 const 변수, 코드 리팩토링(refactoring) (0) | 2023.02.09 |
| Flutter 스터디 17 로그인과 주사위 게임 플러트앱 만들기 (1) | 2023.02.06 |
| Flutter 스터디 16 Stateful Widget (0) | 2023.02.05 |