티스토리 뷰
다트 라이브러리는 Future 또는 Stream 객체를 반환하는 함수들이 많이 있다. 이러한 함수들은 비동기적이다. 즉, 입출력과 같이 시간이 오래 걸릴 수 있는 작업을 요청한 후에도 작업이 완료될 때까지 기다리지 않고 반환되어, 다른 작업을 할 수 있게 된다.
async와 await 키워드는 동기 코드를 비동기 코드와 유사하게 작성할 수 있도록 도와준다.
Future 다루기
완료된 Futurue의 결과가 필요할 때는 두 가지 방법이 있다.
- async와 await를 사용하기
- then()으로 처리하기
async와 await 를 사용하는 코드는 비동기적이지만, 동기 코드와 매우 유사하게 보인다. 예를 들어, 비동기 함수의 결과를 기다리기 위해 await를 사용하는 코드는 다음과 같다.
await lookUpVersion();
await를 사용하려면, 코드는 async로 표시된 함수 내에 있어야 한다.
Future<void> checkVersion() async {
var version = await lookUpVersion();
// 버전과 관련된 작업 수행
}
async 함수는 첫 번째 await 표현식을 만날 때까지 실행되며, 이후 Future 객체를 반환하고 await 표현식이 완료되면 실행을 재개한다.
await를 사용하는 코드에서 오류 처리와 정리를 위해 try, catch, finally를 사용할 수 있다.
try {
version = await lookUpVersion();
} catch (e) {
// 버전을 조회할 수 없는 경우 처리
}
하나의 async 함수 내에서 여러 번 await를 사용할 수 있다. 예를 들어, 다음 코드는 세 번의 비동기 함수 결과를 기다린다.
var entrypoint = await findEntryPoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
await 사용 시 컴파일 타임 오류가 발생하면, await 가 async 함수 내에 있는지 확인하자. 예를 들어, 애플리케이션의 main() 함수에서 await를 사용하려면, main() 함수의 바디를 async로 표시해야 한다.
void main() async {
checkVersion();
print('In main: version is ${await lookUpVersion()}');
}
위의 예제는 main()는 checkVersion()의 결과를 기다리지 않고 사용하고 있다. 이러한 방식은 실행을 마쳤다고 가정하는 코드에서 문제가 발생할 수 있다. 이 문제를 피하려면 unawaited_futures 린터 규칙을 사용하자.
// 추가 설명이 필요함
async 함수 선언
async 함수는 본문이 async 수정자로 표시된 함수이다. 함수에 async 키워드를 추가하면 해당 함수는 Future를 반환한다.
예를 들어, 다음은 String을 반환하는 동기 함수이다.
String lookUpVersion() => '1.0.0';
만약 실행 시간이 많이 소요된다면 async를 사용하여 비동기 함수로 변경하고 반환값은 Future가 된다.
Future<String> lookUpVersion() async => '1.0.0';
비동기 함수는 바디에서 Future로 반환하지 않아도 된다. 필요한 경우 다트가 Future 객체를 생성한다.
값을 반환하지 않는 비동기 함수는 반환 타입을 Future<void>로 만들자.
Stream 다루기
Stream에서 값을 가져와야 할 때는 두 가지 방법이 있다.
- await-for 루프를 사용한다.
- listen()을 사용한다.
참고로 await-for 루프를 사용하기 전에, 이 방법이 코드를 더 명확하게 만드는지, 그리고 스트림의 모든 결과를 기다리는 것이 맞는지 확인하자. 예를 들어, UI 이벤트 리스너에는 await-for를 사용하는 것이 일반적으로 적합하지 않다. UI 프레임워크는 끝없이 이벤트 스트림을 전송하기 때문이다.
await-for 루프는 다음과 같은 형식을 가진다.
await for (varOrType identifier in expression) {
// 스트림이 값을 방출할 때마다 실행됩니다.
}
expression의 값은 Stream 타입이어야 한다. 실행 과정은 다음과 같다.
- 스트림이 값을 방출할 때까지 기다린다.
- 방출된 값을 사용하여 for 루프의 본문을 실행한다.
- 스트림이 종료될 때까지 1과 2를 반복한다.
스트림 청취를 중지하려면, for 루프를 중단하고 스트림 구독을 취소하는 break 또는 return 문을 사용할 수 있다.
await-for 루프 구현 시 컴파일 타임 오류가 발생하면, await-for이 async 함수 내에 있는지 확인하자. 예를 들어, 애플리케이션의 main()에서 await-for 루프를 사용하려면 main() 함수의 본문을 async로 표시해야 한다.
void main() async {
// ...
await for (final request in requestServer) {
handleRequest(request);
}
// ...
}
'다트 공식 문서 번역' 카테고리의 다른 글
다트] 널 안전성 이해하기 (0) | 2024.08.14 |
---|---|
다트] 엄격한 널 안전성 (0) | 2024.08.13 |
다트] 다트에서의 동시성 (0) | 2024.08.12 |
다트] 클래스 수정자 조합 (0) | 2024.08.12 |
다트] API 유지 보수를 위한 클래스 수정자 (0) | 2024.08.11 |