CPU의 일 처리 단위를 Thread라고 한다.
일단 간단하게 Async 개념에 대해 예시를 들어 설명해보면
집안일을 주말에 해야 한다고 가정했을 때
빨래 - 1시간, 설거지 - 30분, 청소기 - 30분이 걸린다고 설정하면
sync인 동기적으로 집안일을 하게되면
빨래 1시간, 설거지, 30분, 청소기 30분을 순차적으로 진행하게 되어 2시간의 시간이 걸리게 된다.
만약 async인 비동기적으로 집안일을 하게된다면
세탁기를 돌려놓고 빨래를 하는 동안 설거지와 청소를 순차적으로 진행하여 1시간의 시간이 걸리게 된다.
보통 서버에 요청하고 기다리는 시간동안 Thread를 차지하지 않고 다른 일처리를 먼저 하는 것이 Async의 개념이다
Future
Future은 미래에 받아올 값을 의미한다.
void main() {
Future<String> name = Future.value('촤촤촤');
Future<int> number = Future.value(123);
}
Futrue에는 delayed인자가 있는데
2개의 파라미터가 존재한다.
1. 지연할 기간(얼마나 지연할 건지) Duration
2. 지연된 시간이 지난 후 실행할 함수
즉 파라미터1만큼 기다렸다가 2번째 함수를 수행한다.
코드로 보면
void main() {
Future.delayed(Duration(seconds: 2), (){
print('Delay 끝');
});
}
이것을 수행하면 2초 runtime 2초 이후에 Delay 끝이 print됨을 볼 수 있다.
쉽게 덧셈으로 async로 수행해보자
void main() {
addNumbers(1,1);
}
void addNumbers(int number1 , int number2) {
print('계산시작 : $number1 + $number2');
//delayed
Future.delayed(Duration(seconds: 2), (){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
}
Future.delayed가 아니였다면
컴퓨터는 순차적으로 계산시작 - 계산완료 - 함수완료를 print했을 것인데
async로 delay 2초를 주게 된다면
계산시작 - 함수완료 - 계산완료 순으로 print가 됨을 알 수 있다.
await
기다리라는 의미이다 말 그대로 순차적으로 수행하기 위해 async함수가 끝난 이후에 순차적으로 수행하기 위함이다
await 키워드를 사용하려면
파라미터와 함수 사이에 async라는 키워드를 적어줘야 사용할 수 있다.
async라는 키워드를 적으면
async로 실행되는 함수들 (= Future를 return 하는 함수) 예를 들어 Future 함수 앞에 await키워드를 넣을 수 있다.
void addNumbers(int number1 , int number2) async { // 여기에 async
print('계산시작 : $number1 + $number2');
//Future앞에 await
await Future.delayed(Duration(seconds: 2), (){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
}
delayed일지라도 계산 시작 - (2초후에) 계산완료 - 함수완료 순으로 출력 됨을 알 수 있다.
그렇다고 계산완료 하는동안 Thread를 잡아 먹고 있는 것은 아니다
이렇게 두 개의 함수를 수행해야 하는 코드를 넣어주면
void main() {
addNumbers(1,1);
addNumbers(2,2);
}
void addNumbers(int number1 , int number2) async {
print('계산시작 : $number1 + $number2');
await Future.delayed(Duration(seconds: 2), (){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
}
await 하는 2초 동안 Thread가 노는 것이 아니고 바로 다음의 순차적으로 수행해야할 코드를 진행을 한다.
그렇기 때문에 위와 같은 코드가 수행됨을 알 수 있다.
그럼 만약 addNumbers(1,1)이 수행을 마치고 addNumber(2,2)를 수행하고 싶을 때는 어떻게 할까?
(=결과가 계산시작 : 1+1 -> 계산완료: 1 + 1 = 2 -> 함수완료 -> 계산시작 2 + 2 -> 계산완료 2+ 2 -> 함수완료)
위에서 배웠듯 await를 써주면 되는데
1. 함수 앞에 await를 써주고
2. await는 Future를 리턴하는 함수 앞에서만 쓸 수 있기 때문에 Future로 감싸준다.
void main() async { // 여기에 async
await addNumbers(1,1); // 함수 앞에 await
await addNumbers(2,2); // 함수 앞에 await
}
// Future 리턴하는 함수여야 하니 void를 Future로 감싸준다.
Future<void> addNumbers(int number1 , int number2) async {
print('계산시작 : $number1 + $number2');
await Future.delayed(Duration(seconds: 2), (){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
}
그래서 위와같은 변형이 필요하다.
Future값으로 return 받고 싶을 때
void main() async {
final result1 = await addNumbers(1,1);
final result2 = await addNumbers(2,2);
print('result1: $result1');
print('result2: $result2');
print('result1 + result2 = ${result1 + result2}');
}
Future<int> addNumbers(int number1 , int number2) async {
print('계산시작 : $number1 + $number2');
await Future.delayed(Duration(seconds: 2), (){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
return number1 + number2;
}
Future<int>로 리턴받고 싶다고 했으면
쉽게 생각해서
return 값을 정해주면 된다 number1 + number2
'Flutter > Dart 문법' 카테고리의 다른 글
[Flutter] list generate (0) | 2023.06.28 |
---|---|
[Dart] Stream (Future와 차이점) (0) | 2023.03.24 |
[Dart] List<Map<>>을 Class로 전환하기(연습) (0) | 2023.03.23 |
[Dart] cascading (0) | 2023.03.23 |
[Dart] List - reduce / List - fold (0) | 2023.03.23 |