JS/JavaScript&TypeScript

JavaScript&TypeScript 15. 생성기 함수

shin96bc 2022. 4. 3. 12:36

(1) 생성기 함수( Generator Function )

     Github: https://github.com/SHIN96BC/JavaScript-TypeScript-Concept-2022/tree/main/15_GeneratorFunction

     1) 일반 함수와 생성기 함수의 공통점
          <1> 코드의 묶음 이다.
          <2> 인자를 받는다.( 받지 않을 수도 있다. )
          <3> 값을 반환한다.( 반환하지 않을 수도 있다. )

     2) 일반 함수와 생성기 함수의 차이점
          <1> 일반 함수는 값을 반환하면 함수가 종료되는데, 생성기 함수는 값을 반환하고 나서 함수가

                 종료될 수도 있고, 종료되지 않을 수도 있다. ( 종료할지 말지 선택할 수 있다. )
          <2> 영원히 종료되지 않게 만들수도있고, 몇번의 반환을 거친 후에 종료될 수도 있고, 

                 일반 함수처럼 바로 종료될 수도 있다.

     3) 생성기 함수( Generator )의 특징
          <1> 함수명과 함수 이름 사이에 애스터리스크 마킹( function* )을 해야한다.
          <2> Generator 는 첫번째 호출을 하면 일반 함수와 달리 자신을 실행시키지 않는다.
          <3> 정확히는 실행시키는데 필요한 도구를 갖고있는 객체를 반환해준다.
          <4> 그 반환된 객체에 담겨진 메소드
               1> next()
                    1. Generator 에서 가장 핵심적인 메소드이다.
                    2. next() 메소드는 Generator 함수 본체의 실행을 재개시킬 수 있는 메소드이다.
                    3. next() 에 인자값을 넣어서 호출하게 되면, 마치 yield 가 마치 리턴한 것처럼 

                        사용할 수 있다.
                         ex) const booster = yield energy;
                             ...
                             Generator객체.next(5);
                             ( 이렇게 하면 booster 에 5 라는 값이 들어가게 된다. )

          <5> 'yield' 키워드
               1> yield 란 Generator 를 멈추는 키워드이다.
               2> 그래서 제어가 yield 키워드를 만나게되면 함수가 멈추게 된다.
                    ex) let energy = 1;
                        const booster = yield energy;

               3> 멈춘 상태에서 yield 뒤에 있는 값을 호출자에게 돌려준다.
                  마치 next() 가 리턴한 것처럼 next() 의 반환값으로 yield 뒤에 있는 값을 반환해준다.

               4> 하지만 그 값을 그냥 반환하는 것이 아니라 객체로 한번 포장해서 반환해준다.
                  value 에 yield 뒤에 있는 값을 넣어주고, 그리고 done 이라고 하는 속성과 함께 포장된다.
                    ex) {value: 1, done: false}

               5> yield 에서 멈춘상태로 next() 가 한번 더 호출되면, 그 다음 코드

                    ( 여기서는 booster 로 대입되는 구간 )가 실행되고, 다시 yield 를 만날때까지 진행된다.

          <6> 'done' 이란 무엇인가?
               1> 이 done 이라고 하는 속성은 Generator 안에서 어떤 상황에 return 을 만날 때까지 

                    false 가 반환된다.
               2> return 문을 만나게되면 함수를 종료하고, done 속성을 true 로 만든다. 

                    즉, 함수가 끝났다는 것이다.

          <7> 생성기 함수는 기존에 실행하고 있던 상태를 모두 다 보존하고 있다.
              ( 그렇기때문에 클로저 공간에 값을 가둬두고 하는 테크닉을 사용하지 않아도 되는 것이다. )

          cf) 일반적으로는 많이 사용하지 않지만, React, Vue.js 같은 프레임 워크 기술을 사용할 때 

               많이 사용된다.

     ex) 
         function* infiniteEnergyGenerator() {
              let energy = 1;
              while(true) {
                   const booster = yield energy;

                   if(booster) {
                        energy += booster;
                   }else {
                        energy++;
                   }
              }
         }

         const energyGenerator = infiniteEnergyGenerator();

         for(let i = 0; i < 5; i++) {
              console.log(energyGenerator.next());
         }

         console.log(energyGenerator.next(5));