개발을 하다보니 비동기 처리가 헷갈려서 한 번 정리를 해봐야겠다라는 생각이 들었다.
Future then vs await async 비교 및 쓰는 법
플러터는 기본적으로 단일 쓰레드로 동작한다. 이말인 즉 코드가 한줄 한줄 실행이 되므로 특정 코드에서 시간이 오래 걸리면 다음으로 넘어 갈 수 없다는 뜻이기도 하다. 하지만 Future then, await&
velog.io
이 게시글의 도움의 받았고, 스스로 정리를 해보려고 한다.
비동기 처리에 대해서 알기 위해서는 프로세스에 대해 먼저 알아야한다. 다음 블로그 글을 보고 오면 이해가 될 것이다.
(추후 업데이트 예정)
비동기 처리란?
비동기 처리란 특정 프로세스의 완료를 기다리지 않고 동시에 다른 작업을 처리하는 방식을 의미한다.
개발을 할 때에는 흔히 서버에 API 요청을 보낼 때 쓰인다.
요청을 보내고 응답을 받을 때까지 delay가 발생할 수 밖에 없는데 이때 마냥 CPU를 놀게 하면, CPU 활용률이 떨어지기 때문이다.
플러터에서의 비동기 처리
플러터는 기본적으로 싱글쓰레드를 사용한다. 싱글쓰레드, 멀티쓰레드에 대해서는 다음 블로그 글을 보고 오면 이해가 될 것이다.
(추후 업데이트 예정)
싱글쓰레드의 특성상 현재 실행중인 지점(코드)는 단 한 줄만이 존재한다. API 요청을 보내면 응답이 언제 올 지도 모르는데, 비동기 처리를 하지 않으면 해당 파일은 전부 응답이 올 때까지 기다리게 되는 것이다. 이는 매우 비효율적이다. 그렇기에 flutter에서는 Future을 지원한다.
Future
future은 이름부터 굉장히 직관적이다. 미래의 이벤트를 기다린다는 뜻으로, 자바스크립트의 Promise와 유사한 개념이라고 보면 된다.
then,await async를 통해서 이를 알아보자.
void main() {
PrintEnglish();
PrintKorean();
}
void PrintEnglish() {
var weatherData = PrintHI();
print(weatherData);
}
Future<String> PrintHI(){
//여기서 CPU는 다른 코드를 실행하고 백그라운드에서 future 리턴값을 기다림
return Future.delayed(
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');
}
다음과 같은 코드가 있다고 해보자.
void main() 함수가 가장 먼저 실행되니, PrintEnglish(); 함수가 가장 먼저 호출이 될 것이다.
PrintEnglish에서는 PrintHI()를 호출한다.
1초동안 기다리는 동안 cpu는 기존의 코드를 실행할 것이다.
print(weatherData)를 실행하지만, 해당 값은 없으니 출력이 의도한 되지 않을 것이고, main()으로 돌아가 "안녕!만나서 반가워"를 출력한다.
실행 흐름을 숫자로 다시 정리를 해보겠다.
void main() {
PrintEnglish(); //1
PrintKorean(); //5
}
void PrintEnglish() {
var weatherData = PrintHI();//2
print(weatherData);//4
}
Future<String> PrintHI(){
//여기서 CPU는 다른 코드를 실행하고 백그라운드에서 future 리턴값을 기다림
return Future.delayed(//3
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');//6
}
출력 결과는 다음과 같다.
Instance of Future String은 print(weatherData)에서 해당 값이 Futre<String> 형태이기에 출력된 것이다.
await 이란?
await이란 async를 포함한 함수에서, await이 포함된 프로세스가 실행 완료 될 때까지 해당 함수의 실행을 막는것이다.
void main() {
PrintEnglish();
PrintKorean();
}
void PrintEnglish() async {
var weatherData = await PrintHI();
print(weatherData);
}
Future<String> PrintHI(){
//여기서 딜레이 발생 시키고 퓨쳐로 리턴
return Future.delayed(
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');
}
다음 코드는 기존의 코드에서 Print English에 await async를 추가한것이다.
PrintEnglish 함수는 await PrintHI() 결과가 반환되기 전에 실행을 멈춘다.
기존에 실행중인 지점인 main() 함수로 돌아가 PrintKorean이 실행되었다,1초가 지난후 future 가 반환되면 기존 await가 실행되었던 PrintEnglish()로 돌아가 print(weather)가 실행이 된다.
출력 결과는 다음과 같다.
then이란?
then은 await/async와 굉장히 유사한 개념으로 이름처럼 직관적으로 이후에 처리함을 의미한다.
코드를 보면 이해가 될 것이다.
void main() {
PrintEnglish();
PrintKorean();
}
void PrintEnglish() {
PrintHI().then(
(value)=>{print(value)}
);
}
Future<String> PrintHI(){
//여기서 딜레이 발생 시키고 퓨쳐로 리턴
return Future.delayed(
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');
}
PrintEnglish에서 then을 사용한 결과 PrintHi가 완료되기 전에는 기존의 main 함수로 돌아간다.
PrintHi가 완료 되면, 결과 값을 value로 받고 이 값을 이용할 수 있게 된다.결과론적으로는 기존의 async,await를 사용한 것과 같은 결과가 도출된다.
그럼 async/await 랑then 차이가 뭔데?
async await는 함수 전체가 실행되지 않고 기다리지만, then은 안에 포함된 코드만 기다린다는 차이점이 있다.
다음 두 코드의 실행 결과를 보면 이해가 빠를 것이다.
void main() {
PrintEnglish();
PrintKorean();
}
void PrintEnglish() async {
var weatherData = await PrintHI();
print(weatherData);
print("이건 중간에서");
}
Future<String> PrintHI(){
//여기서 딜레이 발생 시키고 퓨쳐로 리턴
return Future.delayed(
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');
}
void main() {
PrintEnglish();
PrintKorean();
}
void PrintEnglish() {
PrintHI().then(
(value)=>{print(value)}
);
print("이건 중간에서");
}
Future<String> PrintHI(){
//여기서 딜레이 발생 시키고 퓨쳐로 리턴
return Future.delayed(
Duration(seconds: 1),
(){
return 'HI Nice to Meet You';
}
);
}
void PrintKorean(){
print('안녕! 만나서 반가워');
}
다음과 같이 두 함수의 차이점을 알 수 있다.
포스트를 보고 비동기 처리의 개념에 대해서 잘 알아갔으면 좋겠다.
'Flutter' 카테고리의 다른 글
[Flutter 플러터] 뒤로가기 처리법 (0) | 2023.12.31 |
---|---|
'com.example'은(는) 제한되어 있으므로 다른 패키지 이름을 사용해야 합니다.' (1) | 2023.12.23 |
No 'podfile' found in the project directory 오류 (0) | 2023.12.22 |
[Flutter] fcm 알림이 오는데 팝업 알림이 뜨지 않는 이유 (1) | 2023.12.07 |