본문 바로가기
기타개발/Flutter

Dart #10 - Asychrony support, Generator

by 궝테스트 2020. 8. 28.

Dart : https://dart.dev/guides/language/language-tour

  • Dart 라이브러리는 Future 또는 Stream 객체를 반환하는 함수들이 많으며 이러한 함수는 비동기적이다
  • 작업이 완료 될 때까지 기다리지 않고 시간이 많이 걸리는 작업 (ex: I/O) 을 설정 한 후 반환된다
  • async 및 await 키워드는 비동기 프로그래밍을 지원하므로 동기 코드와 유사한 비동기 코드를 작성할 수 있다
  • 참고 : https://dart.dev/codelabs/async-await

 

1. Declaring async functions

  • async 함수는 본문이 async 한정자로 표시된 함수로 함수에 async 키워드를 추가하면 Future가 반환된다
String lookUpVersion() => '1.0.0';

// async 함수로 변경
Future<String> lookUpVersion() async => '1.0.0';

 

2. Future

  • Dart 라이브러리 전체에 나타나며, 종종 비동기 메서드에 의해 반환되는 객체이다
  • future 는 Future 클래스의 인스턴스이다
  • future 는 비동기 작업의 결과를 나타내며 미완료 또는 완료의 두 가지 상태를 가질 수 있다

2-1. Uncompleted

  • 값을 생성하기 전 future 의 상태를 나타내는 Dart 용어이다
  • 비동기 함수를 호출하면 완료되지 않은 future 가 반환된다
  • 해당 future 는 함수의 비동기 작업이 완료되거나 오류가 발생하기를 기다리고 있는다

2-2. Completed

  • 비동기 작업이 성공하면 future 는 값으로 완료되고 그렇지 않으면 오류와 함께 완료된다

Completing with a value

  • Future<T> 타입의 future 는 T 타입의 값으로 완료된다
  • 예를 들어 Future<String> 은 문자열 값을 생성한다
  • Future 가 사용 가능한 값을 생성하지 않으면 Future 타입은 Future<void> 이다

Completing with an error

  • 어떤 이유로든 함수가 수행한 비동기 작업이 실패하면 future 는 오류와 함께 완료된다

 

3. Handling Futures

  • 완료된 Future 의 결과가 필요한 경우 두 가지 옵션이 있다
    • async 와 await 키워드 사용
    • Future API 사용
  • async 와 await 키워드를 사용하는 코드는 비동기적이지만 동기 코드와 비슷하다
  • 아래 코드는 비동기 함수의 결과를 기다리는데 await 을 사용하는 일부 코드이다
await lookUpVersion();

// await 은 async 키워드가 지정된 async 함수 내에서 사용해야 한다
Future checkVersion() async {
  var version = await lookUpVersion();
  // Do something with version
}

// async 함수에서 await 을 여러번 사용할 수 있다
var entrypoint = await findEntrypoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
  • async 함수는 시간이 많이 걸리는 작업을 수행 할 수 있지만 작업을 기다리지는 않는다
  • 대신 async 함수는 첫 번째 await 표현식을 만날 때까지만 실행된다
  • 그런 다음 Future 객체를 반환하고 await 표현식은 해당 객체를 사용할 수 있을 때까지 실행을 일시 중지하고 완료된 후 ​​실행을 재개한다
// await 을 사용하는 코드에서 try-catch-finally 로 에러를 다룰 수 있다
try {
  version = await lookUpVersion();
} catch (e) {
  // React to inability to look up the version
}
  • await 표현식에서 expression 의 값은 일반적으로 Future 이다
  • 그렇지 않은 경우 값은 자동으로 Future 로 래핑된다
  • await 사용 시 컴파일 타임 오류가 발생하면 await 이 비동기 함수에 있는지 확인해야 한다
  • 예를 들어 앱의 main() 함수에서 await 을 사용하려면 main()의 본문을 async 로 표시해야한다
Future main() async {
  checkVersion();
  print('In main: version is ${await lookUpVersion()}');
}

 

4. Handling Streams

  • 스트림에서 값을 가져와야하는 경우 두 가지 옵션이 있다
    • async 또는 비동기 for loop (await for) 를 사용한다
    • Stream API를 사용한다
  • await for 를 사용하기 전에 코드가 더 명확하고 스트림의 모든 결과를 기다리고 싶은지 확인해야한다
  • 예를 들어, UI 프레임 워크는 끝없는 이벤트 스트림을 전송하기 때문에
    일반적으로 UI 이벤트 리스너에 대해 await를 사용하지 않아야한다
  • 아래 await for 예제에서 expression 의 값은 Stream 유형이어야한다
  • 아래 순서대로 실행한다
    1. 스트림이 값을 방출 할 때까지 기다린다
    2. 방출된 값으로 설정된 변수를 사용하여 for loop 의 내부를 실행한다
    3. 스트림이 닫힐 때까지 1, 2 를 반복한다
  • 스트림 수신을 중지하려면 break 또는 return 문을 사용할 수 있다
await for (varOrType identifier in expression) {
  // Executes each time the stream emits a value.
}
  • 비동기 for loop 를 구현할 때 컴파일 타임 에러가 발생하면 aync 함수 내부에 await for 가 있는지 확인해야 한다
Future main() async {
  // ...
  await for (var request in requestServer) {
    handleRequest(request);
  }
  // ...
}

 

5. Generators

  • 일련의 값을 지연 생성해야하는 경우, generator 함수를 사용할 수 있다

1-1. Synchronous generator

  • Iterable 객체를 반환한다
  • synchronous generator 함수를 구현하려면, 함수 본문에 sync* 로 표시하고 yield 문을 사용하여 값을 제공한다
Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) yield k++;
}
  • generator 가 재귀면 yield* 를 사용하여 성능을 향상시킬 수 있다
Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

1-2. Asynchronous generator

  • Stream 객체를 반환한다
  • asynchronous generator 함수를 구현하려면, 함수 본문에 sync* 로 표시하고 yield 문을 사용하여 값을 제공한다
Stream<int> asynchronousNaturalsTo(int n) async* {
  int k = 0;
  while (k < n) yield k++;
}

'기타개발 > Flutter' 카테고리의 다른 글

Flutter : StatefulWidget & StatelessWidget  (0) 2020.09.13
Dart # 11 : Callable classes, Isolates, Typedefs  (0) 2020.08.28
Dart #9 : Library  (1) 2020.08.28
Dart #8 : Generics  (0) 2020.08.28
Dart #7 : Extension method, Enum, Mixin  (0) 2020.08.28

댓글