[Flutter] async async* yield yield* (Dart)

플러터에서 async async* yield yield* 에 대해 알아보도록 합시다. 애스터리스크(*)가 마치 포인터처럼 보이는데, 그건 아니고요, 😊 특수문자가 없으면 계산 결과(result of an asynchronous computation), 특수문자가 있으면 스트림과 같은 데이터의 연속(sequence of data)을 반환한다는 뜻입니다.

  • async : 비동기 계산 결과를 반환합니다.
  • async* : 비동기 결과에 관한 스트림입니다.
  • yield : async* 함수와 사용하며, 스트림에 계산 결과를 추가합니다.
  • yield* : async* 함수와 사용하며, 각각의 스트림을 추가합니다. (yield each를 뜻해요.)

async

비동기 함수를 사용하여, 계산된 결과(future)를 획득할 수 있습니다. 다음은 데이트타음을 반환하도록 했고요, 1초 이후 현재 시간을 가져오도록 한 예제입니다.

void main() async {
  print(DateTime.now());//2001-01-01 00:00:01.000 (1초)
  DateTime result = await doSomeLongTask();
  print(result);//2001-01-01 00:00:02.000 (2초)
  print(DateTime.now());//2001-01-01 00:00:02.000 (2초)
}

Future<DateTime> doSomeLongTask() async {
  await Future.delayed(const Duration(seconds: 1));
  return DateTime.now();
}

async*

비동기적인 데이터의 시퀀스, 스트림을 획득할 수 있습니다. return 보다는 yield를 사용하여, 함수를 바로 종료하지 않고 스트림을 조회하는 형식으로 활용합니다.

yield

'yield'는 'sync*' 또는 'async*' 메서드에서만 사용할 수 있습니다.

void main() {
  count(3).forEach(print);  
}

Stream<int> count(int n) async* {
  for (int i = 1; i <= n; i++) {
    print("(1)" + i.toString());
    await Future.delayed(const Duration(seconds: 1));
    print("(2)" + i.toString());
    yield i;
    print("(3)" + i.toString());
  }
}

이렇게 사용하지는 않으나, 사용 방법에 대해 안내하려고 추가해 보았습니다. (1)프린트 이후 1초를 기다렸다가, (2)와 (3)에 대한 프린트 결과를 조회합니다.

(1)1
(2)1
1
(3)1
(1)2
(2)2
2
(3)2
(1)3
(2)3
3
(3)3

yield*

yield에 대해 스트림 형식으로 각각 진행하는 방법입니다. 카운트다운 함수를 예제로 간단히 살펴보겠습니다. 재귀 함수 형태로 예제를 사용하였는데, 굳이 이 형태를 취하지 않아도 괜찮습니다.

void main() {
  countDown(3).forEach(print);
}

Stream<int> countDown(int n) async* {
  if (n > 0) {
    print("(1)" + n.toString());
    //yield n;
    yield* countDown(n - 1);
    print("(2)" + n.toString());
  }
}
(1)3
(1)2
(1)1
(2)1
(2)2
(2)3
댓글 쓰기
가져가실 때, 출처 표시 부탁드려요! 감사합니다. 💗