이번 포스팅에서는 Future을 사용해서,
Flutter 에서도 비동기 작업을 할 수 있는 방법을 소개하겠다.
Future가 뭘까?
비동기 작업의 결과를 나타난다.
두 가지 상태( 완료(value 생성), 미완료(value 생성하기 전) ) 를 가질 수 있다.
- 비동기 작업이란?
동기, 비동기 작업으로 나뉜다.
- 동기 작업은 예를 들어, 3개의 동작을 수행해야 할 때, (이를 task1, task2, task3 라고 하자.)
순서대로 하나의 작업이 완전히 완료되면 다음 작업을 수행하는 방식이다.
task1 (block발생, 프로그램이 멈춤) -> 서버로 데이터 요청, 받음 -> task1(나머지 동작 수행) task2 task3
의 과정을 수행한다. 즉, 코드가 반드시 작성된 순서대로 실행된다.
- 이때 비동기 작업은
task1 (block발생, 프로그램이 멈춤) -> 서버로 데이터 요청, 받음 -> task1(나머지 동작 수행) task3
task2 수행
의 과정을 수행한다.
이를 병렬 프로그래밍 이라고 하며, 자원을 효율적으로 쓸 수 있다.
즉, 여러 개의 프로세스(task)가 돌아가고 있고, 멀티태스킹이 되고 있다는 뜻이다.
프로세스마다 각각 동작을 수행하겠지?
이렇게 멀티테스킹이 가능하게 만들어주는 코드가 Future이다.
어떻게 쓰는지 살펴볼까?
1
2
3
4
5
6
7
8
9
10
11
12
13
|
String createOrderMessage () {
var order = getUserOrder();
return 'Your order is: $order';
}
Future<String> getUserOrder() {
// Imagine that this function is more complex and slow
return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}
main () {
print(createOrderMessage());
}
|
cs |
이 코드를 돌려보자.
결과가 어떻게 나오는가?
Your order is: Instance of '_Future<String>'
이렇게 나오면 정상이다.
getUserOrder()에서 'Large Latte'를 리턴하는데 4초가 걸린다.
createOrderMessage()는 getUserOrder()가 'Large Latte'를 리턴할 때 까지 기다렸다가,
'Your order is: $order' 를 리턴해야 하는데, 기다리지 않고 리턴했기 때문에 var order(변수) 에 값을 리턴받지 못한 상태로 메인함수의 print에 'Your order is: $order' 를 리턴한다. 따라서
Your order is: Instance of '_Future<String>' 의 결과가 나오는 것이다.
1
2
3
4
5
6
7
8
|
Future<void> getUserOrder() {
return Future.delayed(Duration(seconds: 3), () => print('Large Latte'));
}
main() {
getUserOrder();
print('Fetching user order...');
}
|
cs |
이 코드를 사용하면 결과는
Fetching user order...
Large Latte
와 같이 출력된다.
getUserOrder(); 가 먼저 실행됐더라도, print('Large Latte');를 수행하기 전에 3초를 대기하기 때문에 나중에 출력된다.
한 번 확인해보자.
그럼 이 Future를 활용하는 방법은?
async , await
로 알아보자
async및 await키워드는 비동기 함수를 정의하고 그 결과를 사용하는 선언적 방법을 제공한다.
async : async함수 본문 앞에 키워드를 사용하여 비동기로 표시할 수 있다.
async function : async함수는 async 키워드로 표시된 함수
await : await키워드를 사용하여 비동기식의 완성된 결과를 얻을 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Future<String> createOrderMessage() async {
var order = await getUserOrder();
return 'Your order is: $order';
}
Future<String> getUserOrder() {
return
Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}
// Asynchronous
main() async {
print('Fetching user order');
print(await createOrderMessage());
}
|
cs |
이 코드를 실행해보자
결과:
Fetching user order
Your order is: Large Latte
2번째 line에 await가 보이는가?
await 키워드를 사용하면, 결과값을 받아올 때 까지 기다렸다가 동작을 수행한다.
이를 통해서, createOrderMessage() 는 getUserOrder() 가 값을 리턴하면, 받아온 후에
값을 리턴한다.
그래서 올바른 출력 결과를 확인할 수 있다.
일단 이렇게 사용할 수 있고
마지막 예제를 보자.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
void createOrderMessage () async {
print('Awaiting user order...');
var order = await getUserOrder();
print('Your order is: $order');
}
Future<String> getUserOrder() {
return Future.delayed(Duration(seconds: 4), () => 'Large Latte');
}
main() async {
countSeconds(4);
await createOrderMessage();
}
void countSeconds(s) {
for( var i = 1 ; i <= s; i++ ) {
Future.delayed(Duration(seconds: i), () => print(i));
}
}
|
결과:
Awaiting user order...
1
2
3
4
Your order is: Large Latte
와 같이 나온다면 잘 했다.
이와같이,
Future.delayed(Duration(seconds: 정수), () => function());
혹은
return Future.delayed(Duration(seconds: 정수), () => 리턴할값);
변수 = await 기다리는function();
와 같은 form으로 사용한다면 딜레이를 줄 수 있고, 비동기식 프로그래밍을 할 수 있다.
짜잔!
여기까지.
출처: https://beomseok95.tistory.com/309
'안드로이드 > Flutter' 카테고리의 다른 글
flutter share through other apps (0) | 2020.04.27 |
---|---|
플러터 위젯 - 화면 표시용 위젯 (0) | 2020.04.23 |
플러터 캘린더를 한국어로 바꾸는 방법 (1) | 2020.04.20 |
Flutter에서 Shared Preferences (캐싱) 사용법 (0) | 2020.04.17 |
Flutter 코드 리팩토링 (0) | 2020.04.16 |