yield에서 멈춘 뒤"실행을 원하는 타이밍에 조금씩 나눠서 실행할 수 있는 함수"
function*으로 정의1. 데이터를 하나씩(lazy evaluation) 스트리밍할 때
function* range(start, end) {
for (let i = start; i < end; i++) {
yield i;
}
}
for (const n of range(1, 5)) {
console.log(n); // 1,2,3,4
}
2. 무한한 시퀀스를 다룰 때
function* infinite() {
let n = 0;
while (true) yield++;
}
3. 이터러블 프로토콜 구현
for...of 루프, 전개 연산자([...]), destructuring 등이 동작하려면 iterable이 필요함const g = function* () {
yield 1;
yield 2;
};
console.log([...g]); // [1, 2]
4. 비동기 흐름 제어(예전 패턴)
function* saga() {
const data = yield callApi('/user');
yield put(action(data));
}
5. 복잡한 상태 머신(state machine)을 단순화
// 일반 구현
function step(state, input) {
if (state === 0) [
if (input === 'A') return 1;
if (input === 'B') return 2;
]
// ... 코드 장황해짐
}
// 제너레이터로 상태 구현
function* machine() {
const x = yield "state A";
const y = yield "state B";
return "done"
}
6. 직접 구현하는 Iterator/AsyncIterator의 편리한 구현체
// 수동 구현
const iterable = {
current: 0,
next() {
return { value: this.current++, done: false };
},
[Symbol.iterator]() {
return this;
},
};
// generator 사용
function* numbers() {
let n = 0;
while (true) yield n++;
}
7. 스트림 처리 (특히 async generator)
for await...of 조합이 좋음async function* events() {
while (true) yield await getNextEvent();
}
제너레이터 함수는 호출되는 순간 실행되지 않고,
내부 실행 컨텍스트를 가지고 있는 iterator 객체를 반환한다
function* gen() { ...}
const it = gen(); // 실행 X!
it.next(); // 이때 실행 시작됨
이 iterator 안에는 다음이 담기게 됨
즉, 제너레이터는 자체 스택 프레임을 들고 있는 객체로 이해하면 맞음
1. 제너레이터는 컴파일 시 "상태 머신"으로 변환된다
// 제너레이터
function* g() {
console.log('A');
yield 1;
console.log('B');
yield 2;
console.log('C');
}
// 엔진 내부적으로 대략 아래와 같이 변환됨
switch (state) {
case 0:
console.log('A');
state = 1;
return { value: 1, done: false };
case 1:
console.log('B');
state = 2;
return { value: 2, done: false };
case 2:
console.log('C');
state = 3;
return { value: undefined, done: true };
}
yield = 현재 상태를 저장하고 외부로 값 반환next() 호출 = 해당 상태로 점프해서 이어서 실행2. next(value)의 의미
function* g() {
const x = yield 1;
}
const it = g();
it.next(); // yield 1 출력
it.next(42); // 42가 'yield 1' 표현식의 값이 됨
yield로 내보낸 값은 next() return값에 들어감