함수형 프로그래밍(제너레이터와 이터레이터)

제너레이터와 이터레이터

제너레이터는 이터레이터이자 이터러블을 생성(리턴)하는 함수이다.

제너레이터 선언

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

위와 같이 순회문을 수정하여 원하는 값만 조회 할 수 있다.

결론

자바스크립트에서는 이터러블이면 순회 할 수 있다. 제너레이터는 위와 같은 문장을 값으로 만들 수 있고 이 문장을 통해서 순회 할 수 있는 값을 만들 수 있기 때문에 어떠한 상태나 값이든 사실상 순회할 수 있게 만들 수 있다.

결국 제너레이터는 어떠한 값이든 순회할 수 있는 이터러블을 쉽게 만들 수 있다.


Written by@[HongDongUk]
공부한 것을 소소하게 적는 블로그.

GitHubFacebook