function* rainbow(){
yield 'Kane';
yield 'Salah';
yield 'Bale';
yield 'Cech';
}
const it = rainbow();
it.next(); // {value: 'Kane', done:false}
it.next(); // {value: 'Salah', done:false}
it.next(); // {value: 'Bale', done: false}
it.next(); // {value: 'Cech', done: false}
it.next(); // {value: undefined, done: false}
generator는 iterator를 통해 자신의 실행을 제어하는 함수이며, 일반적 함수와 차이는 3가지다.
• 선언시에 function 키워드가 아니라 function*로 설정한다.
• 필요시에 호출자에게 제어권을 양보한다.
• 호출 후에 iterator를 반환한 상태에서 next() 메서드를 한 번 더 호출해야 실행된다.
function* interrogate(){
const burger = yield "어떤 버거를 주문하실래요?";
const number = yield "몇 개를 주문하실래요?";
return `${burger}를 ${number}개 주문하셨습니다`;
}
const c = interrogate();
a.next(); // "어떤 버거를 주문하실래요?"
a.next('shrimp burger'); // "몇 개를 주문하실래요?"
a.next(3); // "shrimp burger를 3개 주문하셨습니다"
yield는 철저히 표현식이다. 따라서 next()에 의해서 name은 어떤 값을 받아야 한다. next()가 제너레이터에 값을 전달해서 제너레이터 함수의 실행을 제어하는 것이다.
function* abc(){
yield 'a';
yield 'b';
return 'c';
}
const it1 = abc();
it1.next(); // {value: 'a' , done: false}
it1.next(); // {value: 'b' , done: false}
it1.next(); // {value: 'c' , done: true}
function* abcd(){
return 'c';
yield 'a';
yield 'b';
}
const it2 = abcd();
it2.next(); // {value: 'a', done: true}
it2.next(); // {value: undefined, done: true}
it2.next(); // {value: undefined, done: true}
보통 마지막 yield문 이후에 next()를 호출한 다음 순서에 done이 true가 된다. 하지만제너레이터의 yield문과 return이 같이 나올 때, return의 순서랑 상관 없이 done: true, value: 리턴값으로 나오게 된다. 그 뒤에 이어지는 yield문은 앞의 return에 의해서 done: true가 된다.
하지만 가급적 제너레이터의 반환값은 yield를 사용하도록 권장된다. return문은 중간에 break하는 용도로 사용되는 것이 일반적이다.