콘텐츠로 이동

Generator와 Iterator

Generator는 실행을 중간에 멈췄다가 다시 재개할 수 있는 특별한 함수입니다. function* 문법으로 선언하며, yield 키워드로 값을 하나씩 내보냅니다. Iterator 프로토콜과 함께 지연 평가(lazy evaluation)를 구현할 수 있습니다.

function*으로 선언한 함수는 호출해도 바로 실행되지 않고 Generator 객체를 반환합니다. next()를 호출할 때마다 다음 yield까지 실행됩니다.

function* evens(n) {
while (true) {
yield n;
n += 2;
}
}
const gen = evens(2);
gen.next(); // { value: 2, done: false }
gen.next(); // { value: 4, done: false }
// ... 무한히 반복 가능

yield가 모두 소진되면 done: true가 됩니다.

function* names() {
yield "kim";
yield "han";
yield "lee";
}
const nameGenerator = names();
nameGenerator.next(); // { value: "kim", done: false }
nameGenerator.next(); // { value: "han", done: false }
nameGenerator.next(); // { value: "lee", done: false }
nameGenerator.next(); // { value: undefined, done: true }

Generator를 사용하면 대량의 데이터를 필요한 만큼만 잘라서 처리할 수 있습니다.

const allImages = Array.from({ length: 100 }, (_, i) => `imgUrl${i}`);
function* getImages(images, batchSize = 10) {
let start = 0;
while (start < images.length) {
yield images.slice(start, start + batchSize);
start += batchSize;
}
}
const genImages = getImages(allImages);
genImages.next(); // { value: ["imgUrl0", ..., "imgUrl9"], done: false }
genImages.next(); // { value: ["imgUrl10", ..., "imgUrl19"], done: false }

“더 보기” 버튼을 눌렀을 때 다음 배치를 불러오는 무한 스크롤 패턴에 활용할 수 있습니다.

유사 배열 객체나 이터러블을 배열로 변환하는 메서드입니다. 두 번째 인자로 매핑 함수를 전달할 수 있습니다.

Array.from({ length: 10 }, (_, i) => i + 1);
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Generator와 함께 사용하면 테스트 데이터 생성이나 시퀀스 초기화에 유용합니다.