1개 혹은 0개의 값을 반환하는 일반 함수와는 다르게 여러 개의 값을 필요에 따라 반환yield
할 수 있습니다.
function*
을 통해 Generator 객체를 생성할 수 있습니다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
const generator = generateSequence();
console.log(generator.toString()); // [object Generator]
가장 가까운 yield
문을 만날 때까지 실행되며, value
와 done
property를 가진 객체를 반환합니다.
done
(boolean): iterator가 다음 value
를 생성할 수 있으면 false, 함수 코드 실행이 끝났으면 truevalue
(any): iterator로부터 반환되는 값
done
이 true일 경우,value
는 return 값이다.
generatorObject.next(value)
❶ Using next()
function* gen() {
yield 1;
}
const g = gen(); // "Generator { }"
g.next(); // "Object { value: 1, done: false }"
g.next(); // "Object { value: undefined, done: true }"
❷ Sending values to the generator
function* gen() {
while (true) {
const value = yield null;
console.log(value);
}
}
const g = gen();
g.next(1);
// "{ value: null, done: false }"
g.next(2);
// 2
// "{ value: null, done: false }"
종료 후 next() 호출 시에는 계속 { value: undefined, done: true }
만 return 됩니다.
현재 일시 중단된 위치에 return
문이 삽입된 것처럼 동작하여, parameter로 제공된 value
를 반환하고 Generator를 종료시킵니다.
generatorObject.return(value)
❶ Using return()
function* gen() {
yield 1;
yield 2;
yield 3;
}
const g = gen();
g.next(); // { value: 1, done: false }
g.return('foo'); // { value: "foo", done: true }
g.next(); // { value: undefined, done: true }
❷ Using return() with try...finally
function* gen() {
yield 1;
try {
yield 2;
yield 3;
} finally {
yield 'cleanup';
}
}
const g1 = gen();
g1.next(); // { value: 1, done: false }
// try...catch 실행 전 return()
g1.return('early return'); // { value: 'early return', done: true }
const g2 = gen();
g2.next(); // { value: 1, done: false }
g2.next(); // { value: 2, done: false }
// try...catch 실행 후 return()
g2.return('early return'); // { value: 'cleanup', done: false }
// 값 보존
g2.next(); // { value: 'early return', done: true }
현재 일시 중단된 위치에 throw
문이 삽입된 것처럼 동작하여, 에러 핸들링이 가능하게 한다.
generatorObject.throw(exception)
exception
은 디버깅을 위해 instanceof
Error
인 것이 유용하다.
function* gen() {
while (true) {
try {
yield 42;
} catch (e) {
console.log('Error caught!');
}
}
}
const g = gen();
g.next();
// { value: 42, done: false }
g.throw(new Error('Something went wrong'));
// "Error caught!"
// { value: 42, done: false }
Generator는 Symbol.iterator
method가 존재하기 때문에 Iterable 객체입니다.
따라서 for of
문 사용이 가능합니다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
const generator = generateSequence();
for(let value of generator) {
console.log(value);
}
실행 결과
1
2
위 예시를 보면 알겠지만, 3은 출력되지 않습니다.
{ done: true }
일 때 마지막 value
를 무시하기 때문입니다.
모든 값이 출력되기를 원한다면 yield
로 값을 반환해야 합니다.
function* generateSequence() {
yield 1;
yield 2;
yield 3;
}
const sequence = [...generateSequence()];
console.log(sequence); // [1, 2, 3]
Iterable 객체이므로 Spread Operator도 사용 가능합니다.
next()
method를 가지고 있기 때문에 iterator입니다.
Iterable, Iterator의 자세한 내용은 여기서 확인할 수 있습니다.
Related Content
[JS] Iteration protocols