JavaScript - 제너레이터(Generator)

BigbrotherShin·2020년 3월 12일
2

JavaScript

목록 보기
14/17
post-thumbnail

모던 자바스크립트 입문(아소 히로시, 길벗, 2018)에서 발췌하여 정리한 내용입니다.

제너레이터

제너레이터는 다음과 같은 성질을 지닌 함수입니다.

  • 반복 가능한 이터레이터(iterator)를 값으로 반환한다.
  • 작업의 일시 정지재시작이 가능하며 자신의 상태를 관리한다.

이터레이터 리절트(iterator result)value 프로퍼티done 프로퍼티를 가진 객체입니다.

정의

제너레이터는 function*문으로 정의한 함수이며, 하나 이상의 yield 표현식을 포함합니다.

function* gen() {
  yield 1; // point 1
  yield 2; // point 2
  yield 3; // point 3
}

let iter = gen(); // 이터레이터를 변수 iter에 대입

console.log(iter.next()); // -> Object {value: 1, done: false}
console.log(iter.next()); // -> Object {value: 2, done: false}
console.log(iter.next()); // -> Object {value: 3, done: false}
console.log(iter.next()); // -> Object {value: undefined, done: true}

yield* iterable 문을 사용하면 위의 코드를 더 짧게 쓸 수 있습니다.

function* gen() {
  yield* [1, 2, 3] // yield* 뒤에는 iterable한 객체만 와야 합니다.(String, Array 등)
}
...

실행 과정

  1. 제너레이터 함수인 gen은 호출해도 바로 실행되지 않습니다. 그 대신 이터레이터를 반환합니다.

  2. 이터레이터의 next 메서드가 호출되면 함수의 첫 번째 yield 연산자의 위치까지 실행하며 결괏값으로 이터레이터 리절트(result)를 반환합니다. 이 때 제너레이터 함수의 내부 처리는 포인트 1에서 일시 정지 상태가 됩니다.

  3. next 메서드가 한 번 더 호출되면 함수의 두 번째 yield 연산자의 위치까지 실행하며 iterator result를 반환하고 포인트 2에서 일시 정지 상태가 됩니다.

yield

즉, 제너레이터 함수의 yield는 프로그램이 일시적으로 정지하는 위치입니다.

그리고 제너레이터로 생성한 이터레이터의 next 메서드는 제너레이터 함수의 상태를 일시 정지 상태에서 실행 상태로 바꾸는 역할을 합니다.

yield에 지정한 값을 next 메서드의 반환값(iterator result의 value)이 되어 바깥으로 산출됩니다. yield문의 사용법은 return문의 사용법과 같습니다.

yield;
yield 표현식;

제너레이터로 생성한 이터레이터는 반복할 수 있기 때문에(iterable하기 때문에) for/of 문으로 반복해서 처리(iteration)할 수 있습니다.

function* gen() {
  yield 1; // point 1
  yield 2; // point 2
  yield 3; // point 3
}

let iter = gen(); // 이터레이터를 변수 iter에 대입

for (let v of iter) console.log(v); // 1, 2, 3을 순서대로 표시한다.

무한 반복기 생성

제너레이터는 이터레이터를 생성하여 각 단계의 반복을 제어할 수 있기 때문에 while (true) { ... } 같은 황당한 문법을 활용할 수 있게 해줍니다.

function* generator() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

const gen = generator(); // 이터레이터 생성

gen.next(); // Object {value: 0, done: false}
gen.next(); // Object {value: 1, done: false}
gen.next(); // Object {value: 2, done: false}
.
.
.
profile
JavaScript, Node.js 그리고 React를 배우는

0개의 댓글