지정된 이름에 대한 새로운 제너레이터 함수를 바인딩한다.
제너레이터 함수(generator function)는 일반적인 함수와 달리 제너레이터 함수를 호출하는 호출자에서 실행에 대한 제어를 가능하게 하는 특수한 메커니즘을 갖는 함수이다. 즉 제너레이터 함수는 함수를 호출하는 쪽에서 함수 실행을 일시 중지하고 재개하는 반복적인 처리를 가능하게 한다. 함수가 일시 중지될 때 마다 호출한 곳으로 어떠한 생성 값을 반환할 수 있고 반대로 호출할 때 값을 전달할 수도 있다.
제너레이터 함수는 리터털과 생성자 함수로 생성이 가능하다. 이것은 일반적인 함수와 동일하다. 차이점은 function
키워드 바로 다음에 *
를 붙여서 제너레이터 함수임을 구분하는 것이다. 또한 제너레이터 함수는 GeneratorFunction
객체의 GeneratorFunction()
생성자 함수로도 생성한다. 그러나 일반적으로 리터럴을 선호하고 사용한다.
함수 내부적으로는 yield
라는 독특한 키워드를 사용한다. yield
는 다양한 단어적 의미를 가지고 있지만 여기서는 "산출한다"라는 의미를 가지고 있다. 제너레이터 함수 내부에 yield
문을 다음과 같이 삽입하면 외부의 호출에 따라 실행을 일시 멈추고 <value>
를 반환한다. <value>
는 다양한 유형의 값을 가질 수 있다.
yield <value>
이러한 yield
문을 제너레이터 함수 내부에 필요에 따라 얼마든지 작성할 수 있다. 만약에 <value>
를 생략한 경우에는 실행을 일시 중지하는 것은 동일하고 반환할 값이 없으므로 대신 undefined
를 반환한다.
function* demo() {
yield "a";
yield "b";
yield "c";
}
제너레이터 함수는 먼저 호출을 해서 Generator
객체를 생성해야 한다. 그리고 Generator
객체의 프로토타입 메소드를 사용하여 함수를 제어한다.
가장 많이 사용하는 메소드는 next()
이다. next()
메소드를 호출하면 제너레이터 함수의 yield
문 순서에 따라 yield
키워드를 만나면 일시 중지하고 생성된 값을 반환한다. 다시 next()
메소드를 호출하면 일시 중지된 위치에서부터 다음 yield
를 만날 때까지 실행을 재개한다. next()
메소드에 대해서는 해당 섹션을 참조하기 바란다.
next()
메소드로 제너레이터 함수 제어
function* demo() {
let r = 10 + 10;
yield r;
r += 100;
yield r;
}
const gDemo = demo();
console.log(gDemo.next());
//-> 20
console.log(gDemo.next());
//-> 120
위 코드의 실제 동작은 다음 [제너레이터 함수의 반환]에서 확인하기 바란다.
제너레이터 함수가 값을 반환하는 경우는 몇 가지가 있다. 역시 대표적인 것은 yield
일 것이다. 다른 경우로는 return
이 있다. reutrn
문은 마찬가지로 어떤 값을 반환하지만 전통적인 의미대로 실행을 끝낸다. 즉 더이상의 이후 yield
문은 의미가 없어진다. yield
와 return
키워드 말고 Generator
객체의 메소드(return()
, throw()
)를 통해서도 반환되는 경우가 있다.
yield
또는 return
문이 반환하는 값은 각각의 키워드 다음에 나오는 값이라고 했다. 하지만 실제로는 앞서 이야기 한 값을 포함한 객체를 반환한다. yield
또는 return
문에 의해서 반환되는 객체의 구조는 다음과 같다.
{
value: <value>,
done: <true|false>
}
value
프로퍼티는 실제로 반환되는 값을 가지며 done
프로퍼티는 제네레이터 함수의 동작 상태를 나타낸다. done
은 "끝났다"라는 의미로 제너레이터 함수가 더 이상의 next()
메소드의 호출을 받을 수 없는 경우 다시 말해 제너레이터 함수가 최종 종료된 경우에는 true
로 설정된다. 제너레이터 함수 밖에서는 반환되는 done
의 값을 통해서 제너레이터 함수의 종료 여부를 확인할 수 있을 것이다.
다음 라이브 코드에서 반환되는 값을 확인할 수 있다.
제너레이터 함수는 독특한 작동 방식으로 인해 범용적으로 사용하는 함수 유형은 아니다. 한편으로 제너레이터 함수는 이터레이션 프로토콜(iteration protocol)을 준수하기 때문에 반복적인 처리가 필요한 경우에 꽤 유용할 수 있다. 지금까지는 netx()
메소드를 명시적으로 호출했지만 이터러블(iterable) 객체답게 반복문 처리를 할 수도 있다. 현재 문서에서는 제너레이터 함수의 기본을 다르므로 다음과 같은 간단한 샘플 코드를 소개로 제너레이터 함수의 소개를 마치고자 한다.