생성기 함수 (generator)

jake·2021년 8월 6일
0

JavaScript문법

목록 보기
14/21
post-thumbnail
  • 일반적인 함수 표현
        function makeInfiniteEnergyGenerator() {
            let energy = 0;
            return function (booster = 0) {
                if(booster) {
                    energy += booster;
                }else {
                    energy++
                }
            return energy;
            };
        };
        const energy = makeInfiniteEnergyGenerator();
        for (let i = 0; i < 5; i++) {
            console.log(energy());
        }
        console.log(energy(5));
  • 제너레이터 함수 표현 (function*)
  1. 제네레이터 함수는 첫번째 호출을 하면 일반 함수와 달리 자신을 실행시키지 않는다. 정확히는 실행시키는데 필요한 도구를 갖고있는 객체를 만들어서 넘겨준다.
  2. 만들어진 객체(energyGenrator)는 next() 메서드를 가지고 있는데,
    제네레이터 함수 본체를 실행을 재개시킬 수 있는 함수이다.
  3. for문에서 energyGenrator.next() 로 infiniteEnergyGenrator()를 실행한다.
  4. 그리고 실행된 함수로가서 energy = 1을 주고 const booster = yield energy;로 넘어간다.
  5. yield는 제네레이터를 멈추는 키워드이다. 멈춘 상태에서 yield뒤에 있는 값을 호출자 에게 돌려준다. 호출자는 next()이다.
    즉, next( )의 반환값으로 energy 값을 주는 돌려주는 것이다.
  6. 이때 값을 단순하게 1 그대로 돌려주는게 아니라, 객체로 한번 포장해서 돌려준다. (value에 돌려받은 값을 넣어주고 done이라는 속성과함께)
  7. 값을 호출자에게 돌려주고 난뒤, for문의 0은 끝났고
    이제 i=1일때 next()로 함수가 재개 되면서 yield로 멈췄던 energy의 값이 booster로 대입된다. 그리고 아래 if문이 실행되면서 energy가 2가된다.
  8. while문이 true로 무한 루프이기 때문이 energy가 2가된 상태에서 yield를 만나 2가된 energy값을 next()에게 돌려준다.
  9. 이렇게 반복해서 5까지 나온다.
  10. next( )에 인자값이 들어가면 yield가 booster에게 리턴한 것 처럼 인자값이 들어간다. 즉, booster가 5가 된다.
    그리고 아래 if문이 실행되면서 energy는 10이되고 yield를 만나 멈추고 10을 출력한다.
  11. 실제로는 무한 루프이지만 next( )가 호출되기 전까지는 멈춰있는다.
    다시 재개 될 때 기존의 함수상태를 그대로 유지하고 있기 떄문에 energy값을 클로저 공간에 가둬둘 테크닉을 쓸 필요가없다. 함수가 종료가안되니까.
  12. done속성은 제너레이터가 return값을 가지면 함수를 종료하고 true로 만든다.
    이것을 이용해 마지막에 반환된 값의 done이 true인지 false인지 확인하고, next()로 다시 재개시킬지 말지 판단할때 사용한다.
        function* infiniteEnergyGenrator() {
            let energy = 1;
            while (true) {
                const booster = yield energy; // yield 뒤에 energy 값을 for문 next()의 값으로 돌려준다.
                if (booster){
                    energy += booster;
                }else{
                    energy++;
                }
            }      
        }
        const energyGenrator = infiniteEnergyGenrator(); // 실행되지 않고 실행시키는데 필요한 도구를 갖고있는 객체를 만든 것
        for(let i = 0; i <5; i++){
            console.log(energyGenrator.next()); 
        }
        // i가 0일때 next()라는 메서드를 만나서 infiniteEnergyGenrator() 함수를 실행한다.
        console.log(energyGenrator.next(5));
profile
열린 마음의 개발자가 되려합니다

0개의 댓글