[문제]
Flutter에서 주식 실시간현재가를 받아오는 api 통신을 이용하기 위해 아래와 같이 코드를 짰다.
[원인]
async와 await 를 이용하여 비동기로 구현했는데 리스트가 하나하나 그려지는 문제가 생겼다. 그 이유는 바로 내가 만든 쿠키.. 아니 async와 await의 문제였다. 아직까지는 티가 많이 나지 않지만 나중에 실시간 데이터가 들어온다면 데이터 처리의 속도가 더 걸려 마치 애니메이션 효과처럼 주르륵 나오게 보일 것이다.
아래는 문제의 나의 코드
Future<void> 를 리턴 타입으로 async 함수로 선언하였다. await 키워드를 사용하여 http.post 메서드의 응답을 기다리게 했다. 각각의 요청이 순차적으로 실행되고 이전 요청의 응답을 받은 후 다음 요청을 보내게 된다. 그래서 요청이 순차적으로 처리되고, 다음 요청을 보내기 전에 그전 요청의 응답을 기다리는 현상이 발생하게 되어 주르르를륵 나오게 되는 것이다.
Future<void> requestData() async {
if (_controller.isRequest.value == false || _controller.isFirst) {
_controller.isFirst = false;
_controller.isRequest.value = true;
for (int i = 0; i < _controller.jmCodes.length; i++) {
final headers = {'Content-Type': 'application/json;charset=utf-8'};
final body = jsonEncode({
"trCode": "1",
"rqName": "",
"header": {"tr_id": "1"},
"objCommInput": {"SHCODE": _controller.jmCodes[i]["jmCode"]}
});
final response = await http.post(
Uri.parse('본인uri주소'),
headers: headers,
body: body,
);
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
print (responseData);
if (responseData['TrCode']) {
SiseData siseData = SiseData.fromJson(
responseData["Data"]["output"],
_controller.jmCodes[i]["jmName"]!);
_controller.siseList.add(siseData);
}
} else {
print('Request failed with status: ${response.statusCode}');
}
}
}
}
[개선]
async 키워드 없이 작성하여, http.post 요청을 각각의 Future<void>로 만들어 리스트에 추가한 후, Future.wait 메서드를 통해 모든 요청이 완료될 때까지 기다렸다. 이 방법은 요청을 병렬로 처리하고 각각의 요청은 독립적으로 실행되어 이전 요청의 응답을 기다리지 않는다. 그래서 여러 요청이 동시에 처리 가능해지고 성능이 향상된다.
void requestData() {
List<SiseData?> newDataList = List.filled(_controller.jmCodes.length, null);
List<Future> futures = [];
for (int i = 0; i < _controller.jmCodes.length; i++) {
final headers = {'Content-Type': 'application/json;charset=utf-8'};
final body = jsonEncode({
"trCode": "1",
"rqName": "",
"header": {"tr_id": "1"},
"objCommInput": {"SHCODE": _controller.jmCodes[i]["jmCode"]}
});
Future future = http
.post(
Uri.parse('uri 주소'),
headers: headers,
body: body,
)
.then((response) {
if (response.statusCode == 200) {
final responseData = jsonDecode(response.body);
if (responseData['TrCode']) {
SiseData siseData = SiseData.fromJson(
responseData["Data"]["output"],
_controller.jmCodes[i]["jmName"]!,
);
newDataList[i] = siseData;
}
} else {
print('Request failed with status: ${response.statusCode}');
}
});
futures.add(future);
}
Future.wait(futures).then((_) {
_controller.siseList.assignAll(
newDataList.where((element) => element != null).cast<SiseData>());
});
}
앞으로는 비동기 통신에도 await 를 잘 걸어서 중요도를 파악하고 코드를 구성해야 할 것 같다.
'Flutter' 카테고리의 다른 글
Flutter 깜박임 없이 서서히 페이지 이동하기 (0) | 2024.08.12 |
---|---|
Flutter 현재 위치 불러오기 (0) | 2024.08.06 |
flutter build 하기 (0) | 2024.07.09 |
flutter 스크롤 했을 때 AppBar color 바뀌는 오류 (0) | 2024.07.08 |
flutter [object ProgressEvent] error - Image.network 오류 (1) | 2024.07.02 |