제너레이터와 이터레이터
제너레이터는 이터레이터이자 이터러블을 생성(리턴)하는 함수이다.
function *gen(){
}
제너레이터는 일반함수에 *을 붙여서 선언한다.
const log = console.log
function *gen(){
yield 1;
yield 2;
yield 3;
}
let iterator = gen() // 제너레이터는 이터레이터를 리턴한다.
log(iterator.next()) // {value : 1 , done : false }
log(iterator.next()) // {value : 2 , done : false }
log(iterator.next()) // {value : 3 , done : false }
log(iterator.next()) // {value : undefiend , done : true }
위와 같이 제너레이터를 통해 이터레이터를 쉽게 만들 수 있고 yield
를 통해 몇번의 next() 함수를 호출 할지 정해줄 수 있다.
log(iterator === iterator[Symbol.iterator]()) // true
제너레이터를 통해 만들어진 이터레이터는 심볼 이터레이터 메소드를 가지고 있고 이 메소드를 통해 생성된 이터레이터는 자기 자신이다. 따라서 제너레이터를 통해 만들어진( 제너레이터의 실행 결과 ) 이터레이터는 well-formed 이터러블, 이터레이터이다.
따라서 제너레이터는 for..of문, 전개연산자 등을 순회 가능하다.
for(const a of gen()) log(a) // 1 2 3
function *gen(){
yield 1;
yield 2;
yield 3;
return 100
}
let iterator = gen()
log(iterator.next()) // {value : 1 , done : false }
log(iterator.next()) // {value : 2 , done : false }
log(iterator.next()) // {value : 3 , done : false }
log(iterator.next()) // {value : 100 , done : true }
제너레이터의 값은 이터레이터의 next() 를 통해서 조회 가능하다. 그리고 제너레이터는 return으로 값을 지정해 줄 수 있는데 이 값은 next() 메소드의 done이 true일 때 조회가 가능하다. 단, 이 값은 이터러블을 for..of 문 등을 이용하여 순회 할 때 에는 조회가 되지 않는다.
for(const a of gen()) log(a) // 1 2 3 (100은 없지!)
for(const a of gen()) log(a)
제너레이터는 위와 같은 순회를 할 때 순회되는 값을 아래와 같이
function *gen(){
yield 1;
yield 2;
yield 3;
}
문장으로 표현한 것 이라고 할 수 있다. 따라서
function *gen(){
yield 1;
if(false) yield 2;
yield 3;
}
for(const a of gen()) log(a) // 1 3
위와 같이 순회문을 수정하여 원하는 값만 조회 할 수 있다.
자바스크립트에서는 이터러블이면 순회 할 수 있다. 제너레이터는 위와 같은 문장을 값으로 만들 수 있고 이 문장을 통해서 순회 할 수 있는 값을 만들 수 있기 때문에 어떠한 상태나 값이든 사실상 순회할 수 있게 만들 수 있다.
결국 제너레이터는 어떠한 값이든 순회할 수 있는 이터러블을 쉽게 만들 수 있다.