LHJ

I'm a FE developer.

17. iterable 객체 연습 - Generator2

11 Aug 2020 » codespitz_re

iterator의 구현을 돕는 Generator

const N2 = class {
    constructor (max) {
        this.max = max;
    }
    [Symbol.iterator](){
        let cursor = 0, max = this.max;
        return {
            done: flase,
            next() {
                if (cursor > max) {
                    this.done = true;
                } else {
                    this.value = cursor * cursor;
                    cursor++;
                }
                return this;
            }
        }
    }
}
const generator = function* (max) {
    let cursor = 0;
    while(cursor < max) {
        yield cursor * cursor;
        cursor++;
    }
}

Generator 를 복잡하게 짰을 때 iterator 로 번역은 할 수 있지만.. 번역할 엄두가 안나게 된다.
iterator 로 작성하려면 훨씬 복잡해지기 때문이다.
하지만 이를 도와주는 것이 있다.

babel

Generator 를 짜서 babel을 돌려보면 가공할만한 일이 일어난다.


done과 value는 yield가 한번에 처리한다.
yield가 value를 리턴함으로써 yield하는 동안엔 done이 다 false이다.
더 이상 yield하지 않고 generator를 빠져나올 때 done이 true가 된다.


const generator = function* (max) {
    let cursor = 0;
    while(cursor < max) {
        yield cursor * cursor;
        cursor++;
    }
}

console.log([...generator(5)]); // [0, 1, 4, 9, 16]
console.log(...generator(5)); // 0, 1, 4, 9, 16

for (const v of generator(5)) console.log(v);
// 0
// 1
// 4
// 9
//16

Generator 를 호출하면 iterator 이자 iterable 객체를 return 한다.
그래서 iterable 과 똑같은 결과가 나오게 된다.

Generator 는 계속 호출해도 똑같이 반복한다.
iterable 이자 iterator 객체이기 때문이다. iterator 객체이기만하면 한번 돌고 끝일 것이다.
iterable이자 iterator 객체이기 때문에 계속 반복할 수 있는 것이다.

배열도 마찬가지로 iterable이자 iterator 객체이기 때문에 반복을 계속해도 계속 반복할 수 있는 것이다.

정리

  • iterator - 상태에 대한 관리요소 : 스코프를 활용해서 자율변수 사용 or 인스턴스를 만들어 필드에서 next가 관리
  • generator - 상태에 대한 관리 : 상태를 인자, 지역변수 갱신으로 관리한다. 훨씬 간편하게, 그리고 이해하기 쉽게 관리할 수 있다. 그리고 반복시키는 것도 제어문으로 돌리면되고 yield만 해주면 된다. 코드를 작성하는 부담이 확 줄어든다.