TIL #019
191127 수
오늘 배운 점
<Flutter>
1. Async & Await
- 이 두 syntax는 비동기 데이터 처리를 하기 위한 코드를 좀 더 깔끔하고 읽기 편하게 작성될 수 있도록 돕는다.
Future<int> _loadFromDisk() {}
Future<String> _fetchNetworkData(int id) {}
class ProcessedData {
ProcessedData(this.data);
final String data;
}
Future<ProcessedData> createData() {
return _loadFromDisk().then((id) {
return _fetchNetworkData(id);
}).then((data) {
return ProcessedData(data);
});
}
- 처리된 데이터를 다루는 class가 있고, disk id를 정수형태로 받아온 후 네트워크 데이터를 불러오는 예시가 있다고 하자. (네트워크와 파일 I/O는 비동기적으로 운영되므로 Future값을 내보낸다.) Dart의 Future API로 이 과정을 createData()처럼 then으로 결합시킬 수 있다. 첫번째 future의 완성된 값이 다음 콜백을 위한 매개 변수가 될 수 있도록 하는 것이다. Future API의 장점 중 하나는 이벤트에 따라 코드가 어떻게 분류되는지를 쉽게 확인할 수 있다는 점이다. (이전 TIL에 언급한 대로, 이 경우에는 에러를 다룰 때 catchError, whenComplete 등을 사용한다.)
Future<ProcessedData> createData() async {
final id = await _loadFromDisk();
final data = await _fetchNetworkData(id);
return ProcessedData(data);
}
- async와 await을 사용하면 방금 then을 활용한 chain과 동일한 코드를 위와 같이 synchronous 코드를 작성하는 모양 그대로 Future를 만들 수 있다. await 수식에 따라 코드 줄 별로 예쁘게 정리된 진행상황을 확인할 수 있다. 이 방식대로라면 실행 후 첫번째 await을 마주치면 id를 받을 때까지 기다렸다가 다시 진행되다가 두번째 await을 만나면 id를 가지고 data를 받고, 네트워크 이벤트가 끝나면 그 data를 가지고 반환한다.
- 결국 두 방법 다 같은 event loop가 행동을 제어하고, Future를 활용한다. 차이점은 async/await을 사용하면 함수가 작아지고 더 동기화된 코드처럼 보이게 해준다는 것이다.
- 그렇기 때문에 에러는 동기화 코드에서처럼 핸들링된다. 즉, try, catch를 활용해서 에러를 핸들링한다는 것.
Future<ProcessedData> createData() async {
try {
final id = await _loadFromDisk();
final data = await _fetchNetworkData(id);
return ProcessedData(data);
} on HttpException catch (err) {
print('Network error: $err');
return ProcessedData.empty();
} finally {
print('All done!');
}
}
- 에러 처리를 할 때 추가적인 콜백을 해야 하는 Future API와 달리, 코드를 try로 감싼 후 on ~ catch로 특정 유형의 예외들을 잡아두면 된다.
- 마지막으로 자주 사용되지는 않지만 for문을 활용하여 await을 처리하는 방법을 더 공부해보았다. Stream 형태로 숫자를 받아와서 다 더해주는 함수를 만들어보자.(정확하게는 숫자들이 도착할 때마다 비동기적으로 더해놓고, Stream이 끝나면 그 합을 반환하는 방식이다.) 일반적인 sync 코드와 함께 비교해보면 다음과 같다. 거의 코드 구조는 유지하고, await로 이벤트를 기다리기 전과 후의 실행 명령을 구분해준다.
- 단, 확실히 완료가 될 것임을 아는 stream에만 사용해야 한다. 끝나지 않고 계속 for loop이 대기하게 되는 상황이 생길 수 있기 때문이다!
//동기 데이터 처리
int getTotal(List<int> numbers) {
int total = 0;
for (final value in numbers) {
total += value;
}
return total;
}
//비동기 데이터 처리
Future<int> getTotal(Stream<int> numbers) async {
int total = 0;
await for (final value in numbers) {
total += value;
}
return total;
}
내일 배울 점
<Flutter>
1. Generators (생성자 함수)
2. 마이스튜디오 화면별 진행 상황
더보기
- 아니 벌써..다음주부터 기말고사 시작..!
'삽질하는 개발자 hashblown' 카테고리의 다른 글
프론트엔드 개발자의 TIL #021 (0) | 2019.11.30 |
---|---|
프론트엔드 개발자의 TIL #020 (0) | 2019.11.28 |
프론트엔드 개발자의 TIL #018 (0) | 2019.11.26 |
프론트엔드 개발자의 TIL #017 (2) | 2019.11.25 |
프론트엔드 개발자의 TIL #016 (0) | 2019.11.24 |
댓글