본문 바로가기
아카이브

제너레이터 (generator)

by PilYeooong 2020. 7. 1.

 

제너레이터(generator)

함수의 실행을 중간에 멈추고, 다시 또 재개할 수 있는 기능입니다.
실행을 멈출 때마다 값을 전달 할 수 있기 때문에, 반복문에서 제너레이터가 전달하는 값을 하나씩 꺼내어 사용할 수 있습니다.

제너레이터는 보통의 컬렉션과는 달리 값을 미리 만들어 놓지 않습니다.
값을 미리 만들어 놓으면 불필요하게 메모리를 사용하는 단점이 있지만,  제너레이터를 사용하면 필요한 순간에 값을 계산해서 전달할 수 있기 때문에 메모리 측면에서 효율적입니다.

 


 

제너레이터는 별표 *(asterisk)와 함께 정의된 함수와 그 함수가 반환하는 제너레이터 객체로 구성됩니다.

 

function* generator(){
  yield 10;
  yield 20;
  return 'finished';
}

const gen = generator();

 

generator()는 별표와 함께 정의된 제너레이터 함수이고, yield는 함수의 실행을 멈출 수 있도록 해주는 키워드입니다.

그리고 제너레이터 함수를 실행하면 제너레이터 객체가 반환됩니다.

 


 

제너레이터 객체는 next, return, throw 메서드를 가지고 있습니다.

 

 

먼저 가장 자주 쓰이는 next()에 대한 예시입니다.

 

function* generator() {
  console.log('generator-1');
  yield 10;
  console.log('generator-2');
  yield 20;
  console.log('generator-3');
  return 'finished';
}
const gen = generator();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());

// result

// generator-1
// { value: 10, done: false }
// generator-2
// { value: 20, done: false }
// generator-3
// { value: 'finished, done: true }

 

제너레이터 함수를 실행하면 제너레이터 객체만 반환 될 뿐, 함수 내부의 코드는 실행되지 않습니다.
next()를 호출하면 yield키워드를 만날 때까지 실행되고 데이터를 반환합니다.
그리고 더는 yield 키워드를 만나지 못하게 되면 객체의 done 속성값은 true가 됩니다.

 


 

다음은 return 메서드 입니다.

 

const gen = generator();
console.log(gen.next());
console.log(gen.return('abc'));
console.log(gen.next());

// generator-1
// { value: 10, done: false }
// { value: 'abc', done: true }
// { value: undefined, done: true }

 

return 메서드가 호출된 시점부터 done 속성값은 true로 바뀝니다.

 


 

마지막 throw 메서드 입니다.

 

function* generator() {
  try {
    console.log('generator-1');
    yield 10;
    console.log('generator-2');
    yield 20;
  } catch(e){
    console.log('catch error', e);
  }
}

const gen = generator();
console.log(gen.next());
console.log(gen.throw('에러 발생'));

// generator-1
// { value: 10, done: false }
// catch error 에러 발생
// { value: undefined, done: true }

 

throw 메서드를 호출하면 예외가 발생한 것으로 처리되기 때문에, catch문이 실행됩니다.
이때에도 done 속성값은 true가 됩니다.

 


 

제너레이터 객체는 반복 가능하면서 반복자이기도 합니다.

 

function* generator() {
  yield 10;
  yield 20;
  yield 30;
}
for(const v of generator()){
  console.log(v);
}
const arr = [...generator()];
console.log(arr);

// 10
// 20
// 30
// [10, 20, 30]

 

for of 문을 통해 반복 가능한 객체로 부터 반복자를 얻습니다.
그리고 반복자의 next()를 호출하면서 done의 속성값이 true가 될 때까지 반복합니다.
전개연산자 또한 done의 속성값이 true가 될 때까지 값을 펼쳐냅니다.

 


 

next()메서드를 이용하여 제너레이터 함수로 데이터를 전달하여 소비 시킬 수도 있습니다.

 

function* generator() {
  const a = yield;
  console.log(a);
  const b = yield;
  console.log(b);
}

const gen = generator();
gen.next(); // generator() 실행
gen.next(100); // a에 100 전달
gen.next(200); // b에 200 전달

// 100
// 200

 

이런식으로 활용을 해 볼 수도 있습니다.

'아카이브' 카테고리의 다른 글

200721 / TIL  (0) 2020.07.21
200701 / TIL  (0) 2020.07.01
200630 / TIL  (0) 2020.06.30
200628 / TIL  (0) 2020.06.28
200627 / TIL  (0) 2020.06.27