Flutter 공부하기 - 비동기 프로그래밍 (Future, Async, Await) 기초 및 예제 #1
다트와 플러터도 마찬가지로 비동기 프로그래밍을 지원합니다.
오히려 다른 언어보다도 더 비동기프로그래밍이 중요할 것입니다. 앱이 주 목적이므로 대부분의 코드가 서버와 통신을 주고받는 비동기일 것이기 때문입니다.
오늘은 그래서 비동기 프로그래밍을 가능하게하는 Future, Async 그리고 Await를 학습해봤습니다.
플러터에서는 비동기 프로그래밍을 위해서 기본적으로 Future 를 사용합니다.
플러터를 지원하는 다트 역시 기본적으로는 순차적으로 코드를 실행하게 됩니다.
따라서 accessData에 Duration 타입의 변수를 선언한 뒤 3초의 지연을 발생시키면 showData함수를 실행할 때 accessData 함수를 실행하고 3초 뒤 fetchData 함수를 실행하게 됩니다.
이 경우에는 컴퓨터의 자원이 낭비가 될 수 있을 것입니다. 왜냐하면 3초 동안 아무 작업도 컴퓨터가 하지 않고 대기를 할테니까요.
하지만 아래와 같이 Future.delayed 을 선언하고 지연시간과 처리함수를 입력한 뒤 이후에 처리할 함수를 별도로 입력하면 후에 선언된 함수가 먼저 실행이 되고나서 Future.delayed 내에 있는 함수가 지연시간 이후에 처리되어 출력되게 됩니다.
비동기 프로그래밍이 구현되었다고 볼 수 있는 것입니다.
하지만 비동기 프로그래밍을 구현함에 있어서도 이후 단계의 함수가 Future.delayed 함수 내에서의 처리된 함수의 결과를 가져와야하는 경우가 발생할 수 있습니다.
한 가지 예로 서버에 요청한 값을 가져와 이후 함수의 입력값으로 처리해야 할 경우가 있을 수 있을 것입니다. 이 경우에 async와 await를 통해서 구현할 수 있습니다.
아래와 같이 코드를 변형해봤습니다.
가장 먼저 showData함수 내에 account라는 변수를 설정을 했구요. accessData 함수에서 리턴받은 account 값을 할당해 줬습니다. 그리고 showData 내에서 fetchData 내에 account 값을 인자값으로 다시 넣어줬습니다.
이렇게 되면 fetchData는 account 값을 확실히 전달받아야만 값을 출력할 수 있을 것입니다. 아래 fetchData 함수를 보십시오.
이를 구현하기 위해서 가장 먼저 accessData를 수정해줍니다.
accessData 함수 내에 String 타입의 account 변수를 설정을 했습니다. 아직 값이 없기 때문에 late로 설정을 해준 후, 리턴 타입을 Future<String>으로 변경해줍니다.
그리고해당 함수가 먼저 실행이 되어야 하는 것이기 때문에 async를 accessData 함수 중괄호 안에 입력하고 기다려야하는 Future.delayed 함수 앞에 await를 설정합니다.
또한 showData 함수 역시도 async로 작동하기 때문에 중괄호 앞에 async를 입력하고 accessData가 실행될때까지 기다려야 하므로 accessData 함수 앞에 await를 입력해줍니다.
이렇게 실행하게 accessData 내의 8500만원이 먼저 출력이 되고 나중에 showData 함수에서 startTask, accessData 그리고 fetchData가 순서대로 실행되게 됩니다.
이 부분을 잘 숙지해두면 나중에 서버와 api 통신을 하게 될 때, 쉽게 배울 수 있다고 하니 여러번 반복해서 함께 숙지하도록 해요.
import 'dart:io'; void main() { showData(); } void showData() async { startTask(); String account = await accessData(); fetchData(account); } void startTask() { String info1 = '요청수행 시작'; print(info1); } Future<String> accessData() async { late String account; Duration time = Duration(seconds: 4); if (time.inSeconds > 2) { await Future.delayed(time, () { account = '8500만원'; print(account); }); } else { String info2 = '데이터를 가져왔습니다'; print(info2); } return account; } void fetchData(String account) { String info3 = '잔액은 $account 원 입니다'; print(info3); } | cs |