javascript.info, https://ko.javascript.info/generators
참고 사이트에 내용을 개인적으로 복습하기 편하도록 재구성한 글입니다.
자세한 설명은 참고 사이트를 살펴보시기 바랍니다.
일반 함수는 하나의 값(혹은 0개의 값)만을 반환합니다. 하지만 제너레이터를 사용하면 여러 개의 값을 필요에 따라 하나씩 반환할 수 있습니다.
제너레이터를 생성하려면 function*
문법으로 작성되는 제너레이터 함수가 필요합니다.
function* createGenerator() {
yield 1;
yield 2;
yield 3;
}
일반 함수는 호출하여 코드를 실행시키는 동작이지만, 제너레이터 함수는 호출 시 제너레이터 객체를 반환하고 이 객체가 실행을 처리하게 됩니다.
function* createGenerator() {
yield 1;
yield 2;
yield 3;
}
// 제너레이터 함수는 제너레이터 객체를 생성합니다.
const generator = createGenerator();
next()
메서드는 제너레이터 객체의 주요 메서드입니다. next()
메서드를 호출하면 가장 가까운 yield <value>
문을 만날 때까지 실행이 지속됩니다(value
를 생략할 수도 있는데, 이 경우엔 undefined
가 됩니다). 이후, yield <value>
문을 만나면 실행이 멈추고 산출하고자 하는 값인 value
가 바깥 코드에 반환됩니다.
next()
는 항상 산출할 값을 지닌value
프로퍼티와 함수의 코드 실행이 끝났는지를 알려주는 done
프로퍼티를 지닌 {value: 값, done: boolean}
객체를 반환합니다.
function* createGenerator() {
yield 1;
yield 2;
yield 3;
}
// 제너레이터 함수는 제너레이터 객체를 생성합니다.
const generator = createGenerator();
console.log(generator.next()) // {value: 1, done: false}
console.log(generator.next()) // {value: 2, done: false}
console.log(generator.next()) // {value: 3, done: false}
console.log(generator.next()) // {value: undefined, done: true}
done
프로퍼티가 true
가 된 시점부터 제너레이터는 종료되었습니다.
제너레이터 함수 내부의 yield
연산자는 결과를 바깥으로 전달할 뿐만 아니라 값을 제너레이터 안으로 전달하기까지 하는 양방향의 길과 같은 역할을 합니다.
값을 안, 밖으로 전달하려면 generator.next(arg)
를 호출해야 합니다. 이때 인자 arg
는 yield
의 결과가 됩니다.
예시를 살펴보겠습니다.
function* createGenerator() {
// 질문을 제너레이터 밖 코드에 던지고 답을 기다립니다.
const result = yield "2 + 2 = ?";
console.log(result);
}
const generator = createGenerator();
console.log(generator.next()); // {value: "2 + 2 = ?", done: false}
console.log(generator.next(4));
// 4
// {value: undefined, done: true}
generator.next()
를 처음 호출할 땐 항상 인수가 없어야 합니다. 인수가 넘어오더라도 무시됩니다. generator.next()
를 호출하면 실행이 시작되고 첫 번째 yield "2 + 2 = ?"
의 결과가 반환됩니다. 이 시점에서 제너레이터는 실행을 잠시 멈춥니다. 그리고 yield
의 결과가 console.log(generator.next())
를 통해 출력됩니다.
그 후, generator.next(4)
를 호출하면 제너레이터가 다시 시작되고 4
는 result
에 할당되고 console.log(result)
를 통해 출력됩니다. 그리고 console.log(generator.next(4))
의 결과로 {value: undefined, done: true}
가 출력되고 제너레이터가 종료됩니다.
setTimeout(() => console.log(generator.next(4)), 1000)
로 비동기 처리를 통해 1초 뒤에 호출해도 상관없습니다. 제너레이터가 기다려주기 때문에 호출을 나중에 해도 문제가 되지 않습니다.
일반 함수와 다르게 제너레이터와 외부 호출 코드는 next()
와 yield
를 이용해 결과를 전달 및 교환합니다.