ES6 문법(4) - Generator

ground4ekd·2020년 11월 20일
0

ECMAScript6 문법

목록 보기
4/4

제너레이터(Generator)는 함수의 실행을 중간에 멈추고 재개할 수 있는 독특한 기능이다. 제너레이터를 사용하는 이유는 많지만 크게보면 세가지로 볼 수 있다.

  • 비동기 코드를 동기 방식으로 작성가능하다.
  • Iterator 와 Iterable을 쉽게 사용가능하다.
  • 느긋한 계산(Lazy-Evaluation)을 통해 필요할 때 값을 사용하여 메모리를 효율적으로 사용할 수 있다.

느긋한 계산(Lazy-Evaluation)이란 값이 필요하지 않을 때는 대기하고 있다가 필요할 때가 되면 값을 요구하는 것을 말한다.

문법

기본

제너레이터의 기본적인 문법으로 yieldnext가 있다. yield는 기본적으로 데이터를 반환하고 함수의 실행을 멈춘다. next메서드는 제너레이터 함수를 다시 실행시켜 yield 뒤에 있는 값을 { value, done } 형태로 반환 시킨다.

function* generator(){
  yield 10
  yield 20
  console.log('hi')
  yield 30
}

const gen = generator()
console.log(gen.next())  // { value: 10, done: false }
console.log(gen.next())  // { value: 20, done: false }
console.log(gen.next())  // hi 
                         // { value: 30, done: false }
console.log(gen.next())  // { value: undefined, done: true }

next 메서드를 세번째 호출할 때 console.log('hi') 가 실행되는 것으로 함수의 실행이 멈추는 것이 확인된다.
마지막 yield를 지나게 되면 { value: undefined, done: true }가 반환된다.

next 인자

next메서드에 인자를 넣으면 제너레이터 함수에 값을 넣을 수 있다.

function* generator(){
  const a = yield 10
  const b = 5
  yield a + b
}

const gen = generator()

console.log(gen.next())    // { value: 10, done: false }
console.log(gen.next(20))  // { value: 25, done: false }

첫번째 next 호출에 yield 10이 반환되었고, 두번째 호출 next(20) 에 인자로 준 20a 변수에 값이 들어가게 되어 20 + 5 인 25가 반환되었다.


사용 예시

비동기 프로그래밍

제너레이터는 비동기적 코드를 동기적 형태로 작성가능하게 해준다.

function* asyncGenerator(){
  const a = yield Promise1();
  console.log(a);

  const b = yield Promise1();
  console.log(b);

  const c = yield Promise1();
  console.log(c);
}

위의 함수 형태가 async-await와 비슷한 것을 확인할 수 있다. 실제로 바벨에서 async-await 을 ES5로 변경할 때 제너레이터를 사용한다.


Iterator

Iterator 조건으로 next 메서드와 반환값이 { value, done } 형태여야 했는데, 제너레이터는 전부 해당되기 때문에 iterator를 편하게 작성할 수 있게 도와준다.

function* generator(){
  const arr = this
  for(let i = 0; i < arr.length; i++){
    yield arr[i] + 1
  }
}

const arr = [1, 2, 3]
arr[Symbol.iterator] = generator

console.log([...arr])  // [2, 3, 4]

또한 제너레이터 객체 자체가 Iterable 이라서 반복이 가능하다.

function* generator(){
  yield 10
  yield 20
  yield 30
}

const gen = generator()
for(let i of gen){
  console.log(i)  // 10 20 30
}

Infinite Data Generator

일반적으로 반복문이 무한적으로 실행되면 스택오버플로우가 일어나 에러가 발생한다. 하지만 제너레이터는 함수의 실행을 멈추고 필요할 때만 실행하기 때문에 에러가 발생하지 않는다.

function * randomize() {
  while (true) {
    let random = Math.floor(Math.random()*1000);
    yield random;
  }
}

var random = randomize();
console.log(random.next().value) // 351
console.log(random.next().value) // 100
console.log(random.next().value) // 235
profile
오늘 뭐라도 하나 했다는 것

0개의 댓글