2.1 제너레이터 문법
JavaScript의 제너레이터는 코드 실행을 제어할 수 있는 특별한 함수야. 실행을 중지하고 나중에 재개할 수 있어서 비동기 코드, 이터레이터, 복잡한 작업에 유용한 도구야.
제너레이터는 function*
으로 정의돼 (별표에 주의해). 제너레이터 안에서는 yield
를 사용해서 실행을 중지하고 값을 반환할 수 있어.
제너레이터 선언:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
제너레이터 객체 생성
제너레이터를 호출해도 코드 본체가 즉시 실행되지 않아. 대신 제너레이터 객체를 반환하지, 이걸로 값을 반복할 수 있는 거야:
const gen = generatorFunction();
2.2 제너레이터 사용
next() 메서드
next()
메서드는 다음 yield
까지 제너레이터 실행을 재개해. 이 결과는 두 개의 속성을 가진 객체로 반환돼:
value
:yield
에 의해 제공된 값done
: 제너레이터가 완료(true)됐는지 아닌지(false)를 나타내는 논리값
next() 메서드 사용 예시:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }
제너레이터 반복
제너레이터는 for...of
루프와 함께 사용해서 값을 반복할 수 있어.
제너레이터 반복 예시:
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
const gen = generatorFunction();
for (const value of gen) {
console.log(value);
}
// 출력: 1
// 출력: 2
// 출력: 3
값 반환 예시
제너레이터는 return
키워드를 사용해서 값을 반환할 수 있어:
function* generatorFunction() {
yield 1;
yield 2;
return 3;
yield 4; // 이 yield는 절대 실행되지 않아
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: true }
console.log(gen.next()); // { value: undefined, done: true }
2.3 복잡한 제너레이터 사용법
제너레이터와 상호작용
next()
메서드는 제너레이터에 전달될 수 있는 인자를 받아서 내부적으로 사용할 수 있어.
제너레이터에 값 전달 예시:
function* generatorFunction() {
const value1 = yield 1;
const value2 = yield value1 + 2;
yield value2 + 3;
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next(10)); // { value: 12, done: false }
console.log(gen.next(20)); // { value: 23, done: false }
console.log(gen.next()); // { value: undefined, done: true }
에러 처리
제너레이터는 try...catch
블록을 사용해서 오류를 처리할 수 있어.
에러 처리 예시:
function* generatorFunction() {
try {
yield 1;
yield 2;
} catch (error) {
console.log('Error caught:', error);
}
}
const gen = generatorFunction();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Something went wrong'))); // Error caught: Error: Something went wrong
// { value: undefined, done: true }
무한 시퀀스를 생성하는 제너레이터 예시
제너레이터는 무한 시퀀스를 생성하는 데도 사용할 수 있어:
function* infiniteSequence() {
let i = 0;
while (true) {
yield i++;
}
}
const gen = infiniteSequence();
console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// 계속해서
2.4 실용적인 사용 예시
예시 1: 객체를 순회하는 제너레이터
function* objectEntries(obj) {
const keys = Object.keys(obj);
for (const key of keys) {
yield [key, obj[key]];
}
}
const obj = { a: 1, b: 2, c: 3 };
const gen = objectEntries(obj);
for (const [key, value] of gen) {
console.log(`${key}: ${value}`);
}
// 출력:
// a: 1
// b: 2
// c: 3
예시 2: 간단한 이터레이터 구현을 위한 제너레이터
const myIterable = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
for (const value of myIterable) {
console.log(value);
}
// 출력: 1
// 출력: 2
// 출력: 3
JavaScript의 제너레이터는 코드 실행을 관리하고, 이터레이터를 만들며 비동기 작업과 관련된 코드에 매우 유용한 도구야. 제너레이터의 문법과 사용법을 이해하면 데이터 시퀀스와 비동기 작업을 다룰 때 더 유연하고 읽기 쉬운 코드를 작성할 수 있어.
GO TO FULL VERSION