네트워크 요청 등을 여러차례 해야되는 경우 이전 작업이 끝나기를 기다렸다가 다음 작업을 진행하게 되면 시간이 그만큼 많이 걸리게된다.
시간이 오래 걸리면 사용자의 입장에서는 렉이 걸린것인지, 진행되고있는지 의문이 들고, 사용자의 이탈으로 이어지게된다.
이번 포스팅에서는 다중요청. 즉, 요청 후 응답까지 시간이 걸리는 여러개의 작업을 한번에 해보자.
한 눈에 봐도 여러개의 작업을 동시에 요청할 경우 소요 시간이 확 줄어드는 것을 볼 수 있다.
네트워크 요청에 걸리는 시간을 가정하기 위해 Future.delayed를 이용해 코드를 작성한다.
Future<void> checkInt(int i) async {
int rndInt = Random().nextInt(3)+1;
print("in $i");
await Future.delayed(Duration(seconds: rndInt));
print("return $i: $rndInt");
}
랜덤으로 1~3값을 받아서 출력하는 코드
Future.delayed를 이용해 딜레이를 준다.
다음으로 main에서 이 코드를 여러차례 호출해보는 코드를 작성한다.
void main() async {
for (int i = 0; i < 5; i++) {
await checkInt(i);
}
}
앞서 작성한 checkInt메소드를 5회 호출하는 코드.
이렇게만 해서는 값이 출력되는것을 확인할 수 없으니 조금 수정해보자.
void main() async {
DateTime start = DateTime.now();
for (int i = 0; i < 5; i++) {
int result = await checkInt(i);
print("result $i : $result");
}
DateTime end = DateTime.now();
print("소요 시간: ${end.difference(start)}");
}
Future<int> checkInt(int i) async {
int rndInt = Random().nextInt(3)+1;
print("in $i");
await Future.delayed(Duration(seconds: rndInt));
print("return $i: $rndInt");
return rndInt;
}
출력 결과
delay가 적용되긴했지만 우리가 원했던, 모든 요청을 먼저 다 하고 결과를 기다리는 그림은 아니다.
코드를 살펴보자. checkInt을 요청할 때 await가 적용되어, return값을 받을 때까지 더이상 진행하지않고 기다리게 된 것을 볼 수 있다.
그렇다면 일단 모든 요청을 다 보내고, 결과를 기다리려면 어떻게 해야될까?
결론부터 말하자면 Future.wait를 이용하면 된다.
먼저 Future.wait를 이용한 코드를 보자.
import 'dart:math';
import 'dart:async';
List<int> checkIntValues = [];
void main() async {
DateTime start = DateTime.now();
final task = <Future>[];
for (int i = 0; i < 5; i++) {
task.add(checkInt(i));
checkIntValues.add(0);
}
await Future.wait(task);
DateTime end = DateTime.now();
print("Values?: ${checkIntValues.map((e) => e)}");
print("소요 시간: ${end.difference(start)}");
}
Future<void> checkInt(int i) async {
int rndInt = Random().nextInt(3)+1;
print("in $i");
await Future.delayed(Duration(seconds: rndInt));
print("return $i: $rndInt");
checkIntValues[i] = rndInt;
}
가장 상단의 checkIntValues List는 결과값을 담아두기 위한 전역변수이다.
해당 변수를 선언한 이유는 Future타입에 저장된 변수를 await 없이 불러오게 되면 값을 받을 수가 없기때문에 다른 변수를 선언하고 완료될 때 값을 담아준다.
여러 메소드를 저장해두기 위해 task변수를 Future타입으로 선언하고
checkInt메소드를 await구문 없이 호출해서 task변수에 담아둔다.
! 여기서 task는 값을 저장하기 위해서가 아닌, 해당 메소드가 끝나는 것을 확인하기 위한것임을 기억하자.
checkInt메소드에서 요청이 완료되면 앞서 선언한 checkIntValues에 값을 저장한다.
- 값을 저장할 필요가 없다면 저장변수는 선언하지 않아도 된다.
await Future.wait(task);
//task에 저장된 모든 요청이 완료되기를 기다린 후, 값이 정상적으로 저장되었는지 출력해본다.
결과
요청이 모두 먼저 들어간 후, 모든 요청이 완료되고 값이 출력되었고, 소요 시간 역시 확연하게 줄어든 것을 확인할 수 있다.
'Develop' 카테고리의 다른 글
flutter> ios에서 Google Signin(Login) 오류날때 (0) | 2022.08.05 |
---|---|
flutter) firebase - database 사용하기 (0) | 2022.07.09 |
Flutter) POD 에러 (Cocoapods 에러 / firebase) (0) | 2022.07.08 |
flutter) Firebase 연동하기 <Mac> (0) | 2022.07.08 |
Flutter - List.map (0) | 2022.06.29 |
댓글