ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Flutter] 플러터 async*/ yield / yield* 키워드
    플러터 Flutter 2021. 4. 25. 18:20
    반응형
    • 주로 bloc패턴에서 많이 사용 된다.
    • async* : async*는 제너레이터를 만든단 뜻. 제너레이터는 게으르게(lazily) 데이터 연산을 할 때 쓰인다. 게으르다는 건 미리 연산을 다 하는 게 아니라, 요청이 있을때까지는 연산 하는 걸 미루어 두었다가 필요할 때 처리하는 걸 뜻한다.
    • yield : return이랑 유사하다. return은 한번 리턴하면 함수가 종료되지만, yield는 종료되지 않는다. yield는 열린 채로 있어서 필요할 때 다른 연산을 할 수 있다.
    • yield Iterable 또는 Stream에서 값을 반환한다.
    • yield* Iterable 또는 Stream 함수를 재귀 적으로 호출하는 데 사용된다.

    아래는 기본적인 예제

    <컴파일 가능한 웹사이트>

    dartpad.dev/embed-inline.html?id=15d5ef986238c97dbc14&ga_id=receiving_stream_events

    importimport 'dart:async';
    
    Future<int> sumStream(Stream<int> stream) async {
      
      var sum = 0;
      
      await for (var value in stream){
        print('sumStream >>>>>>>>>>>>>>>>  $value');
        sum += value;
      }
    
      return sum;
    }
    
    //비동기
    //async*와 yield 키워드를 이용해서 비동기 함수로 만든다.
    //이 함수는 for문을 이용해서 1부터 int형 매개변수 to로 전달받은 숫자까지 반복한다.
    // return은 한 번 반환하면 함수가 끝나지만 yield는 반환 후에도 계속 함수를 유지한다.
    // 이렇게 받은 yield값을 인자로 sumStream() 함수를 호출하면 이 값이 전달될 때마다 
    // sum 변수에 누적해서 반환해준다.
    Stream<int> countStream(int to) async* { // async*는 yield를 쓴다는 의미다.
      print('매개변수 to :  ${to}');
      //yield는 계속 to의 갯수만큼 1번씩 함수를 리턴한다.
      for (int i = 1; i <= to; i++){
        yield i;
        print('countStream의 yield');
      }  
      for (int i = 1; i <= to; i++){
        print('그냥 for문? ${i}');
      }
    }
    
    main() async {
      
      var stream = countStream(10);
      var sum = await sumStream(stream);  
      print('총합 >>>>>>>>>>>>>>>>>> ${sum}');
      
    }

     

    참고 사이트 software-creator.tistory.com/9

    형태 1

    다음은에서 start에서 finish 까지 계산하는 Iterable리턴하는 함수다.

    Iterable<int> getRange(int start, int finish) sync* {
      for (int i = start; i <= finish; i++) {
        yield i; //yield키워드는 각 반복에서 값을 반환한다.
      }
    }
    
    
    void main() {
      getRange(1,3).forEach(print);
    }

    형태 2

    이제 위의 함수를 재귀함수로 재구성 해보자. 외부에서는 여전히 이전과 동일한 작업을 수행한다.

    //이것은 작동하지만 읽기가 어렵고 루프 때문에 그다지 효율적이지 않다.
    Iterable<int> getRange(int start, int finish) sync* {
      if (start <= finish) {
        yield start;
        for (final val in getRange(start + 1, finish)) {
          yield val;
        }
      }
    }
    
    void main() {
      getRange(1,3).forEach(print);
    }

    형태 3

    yield*( "yield star"라고 하기도함)로 바꿔보자

    Iterable<int> getRange(int start, int finish) sync* {
      if (start <= finish) {
        yield start;
        yield* getRange(start + 1, finish);
      }
    }
    
    void main() {
      getRange(1,3).forEach(print);
    }

    여전히 재귀 적이지만 이제 더 읽기 쉽고 더 효율적이다.

     

    <참조>

    stackoverflow.com/questions/55776041/what-does-yield-keyword-do-in-flutter/55776106

    stackoverflow.com/questions/57492517/difference-between-yield-and-yield-in-dart

    flutteragency.com/what-is-yield-keyword-in-flutter/

    반응형

    댓글

Designed by Tistory.