함수의 실행 중 멈췄다가 다시 재개할 수 있는 독특한 기능이다.
C언어의 포인터처럼 함수에 *을 붙여서 선언한다.
function* generatorFunc(){
}
실행을 멈추면서 값을 하나씩 꺼내서 전달할 수 있다.
제너레이터는 일반 함수와 달리 함수를 호출하면 제너레이터 객체를 반환한다.
function* generatorFunc(){
}
const generator = generatorFunc(); //[object Generator] 생성
제너레이터는 값을 미리 만들어 놓지 않고 필요한 순간에 값을 계산하여 전달하기 때문에 메모리 측면에서 효율적이다.
제너레이터가 실행을 멈추는 것은 yield 키워드를 통해서 할 수 있다
function* generatorFunc(){
yield 10;
yield 20;
return 'finished'
}
const generator = generatorFunc(); //[object Generator] 생성
우리가 yield를 만나기 전에는 코드를 멈추게 된다. 따라서 10이라는 value를 yield를 통해 전달하려면 제너레이터 객체의 next()라는 메소드를 사용해야 한다.
function* generatorFunc(){
yield 10;
yield 20;
return 'finished'
}
const generator = generatorFunc(); //[object Generator] 생성
const nextgen = generator.next(); // {value : 10, done: false}
우리가 next() 메소드를 사용하면 제너레이터 객체의 가장 가까운 yield <value>를 만날 때 까지 실행한다. 함수의 프로퍼티 중 done은 함수의 코드가 종료되었을 때 true를 반환하기 때문에 아직 모든 yield를 실행하지 않았음으로 false인 상태다.
function* generatorFunc(){
yield 10;
yield 20;
return 'finished'
}
const generator = generatorFunc(); //[object Generator] 생성
const nextgen1 = generator.next(); // {value : 10, done: false}
const nextgen1 = generator.next(); // {value : 20, done: false}
const nextgen1 = generator.next(); // {value : 'finished', done: true}
next() 메서드를 통해 함수가 종료되는 시점인 return에 다다르면 value가 return 값으로 변하고 done의 값이 true로 변한다.
또한, 제너레이터는 iterable 객체이다.
//배열도 next()메소드를 가지고 있고 value와 done이라는 프로퍼티를 지니고 있다.
const arr = [10, 20, 30];
const iter = arr[Symbol.iterator]();
console.log(iter.next()); // {value: 10, done: false}
function* generatorFunc(){
yield 10;
yield 20;
yield 30;
}
for (const c of generatorFunc()){
console.log(v); //done이 true가 될 때까지 next()를 실행하며 반복.
}
const arr = [...generatorFunc()]; // 전개연산자도 next()를 통해 done이 참이 될 때까지 반복한다.
console.log(arr); //[10, 20, 30]
제너레이터 함수끼리 호출할 때는
yield키워드에 *을 붙여서 호출한다
yield* generatorFunc();
그리고 제너레이터는 외부로부터 데이터를 받아서 소비할 수도 있다.
function* generatorFunc(){
const data1 = yield;
console.log(data1);
const data2 = yield;
console.log(data2);
}
const generator = generatorFunc(); //[object Generator] 생성
const nextgen1 = generator.next(10) //next()메소드의 인수로 값을 전달하여 할당하였다.
제너레이터는 보았다싶이 다른 함수와 협업 멀티태스킹을 할 수 있다.
//제너레이터 함수 선언
function* minsu(){
const myMsgList = [
'안녕 나는 민수야',
'만나서 반가워',
'내일 영화 볼래?',
'시간 안 되니?',
'내일 모레는 어때?'
];
for (const msg of myMsgList){
console.log('수지: ', yield msg);
}
}
function suji() {
const myMsgList = ['', '안녕 나는 수지야', '그래 반가워', '...'];
const gen = minsu();
for (const msg of myMsgList){
console.log('민수: ', gen.next(msg).value);
}
}
suji();
/* 실행결과
민수 : 안녕 나는 민수야
수지 : 안녕 나는 수지야
민수 : 만나서 반가워
수지 : 그래 반가워
민수 : 내일 영화볼래?
수지 : ...
민수 : '시간 안되니?'
*/
제너레이터를 통해 다른 함수와 멀티태스킹을 할 수 있다는 것을 알게 되었다.
참고 : 실전 리액트 프로그래밍