제너레이터(generator)
함수의 실행을 중간에 멈추고, 다시 또 재개할 수 있는 기능입니다.
실행을 멈출 때마다 값을 전달 할 수 있기 때문에, 반복문에서 제너레이터가 전달하는 값을 하나씩 꺼내어 사용할 수 있습니다.
제너레이터는 보통의 컬렉션과는 달리 값을 미리 만들어 놓지 않습니다.
값을 미리 만들어 놓으면 불필요하게 메모리를 사용하는 단점이 있지만, 제너레이터를 사용하면 필요한 순간에 값을 계산해서 전달할 수 있기 때문에 메모리 측면에서 효율적입니다.
제너레이터는 별표 *(asterisk)와 함께 정의된 함수와 그 함수가 반환하는 제너레이터 객체로 구성됩니다.
function* generator(){
yield 10;
yield 20;
return 'finished';
}
const gen = generator();
generator()는 별표와 함께 정의된 제너레이터 함수이고, yield는 함수의 실행을 멈출 수 있도록 해주는 키워드입니다.
그리고 제너레이터 함수를 실행하면 제너레이터 객체가 반환됩니다.
제너레이터 객체는 next, return, throw 메서드를 가지고 있습니다.
먼저 가장 자주 쓰이는 next()에 대한 예시입니다.
function* generator() {
console.log('generator-1');
yield 10;
console.log('generator-2');
yield 20;
console.log('generator-3');
return 'finished';
}
const gen = generator();
console.log(gen.next());
console.log(gen.next());
console.log(gen.next());
// result
// generator-1
// { value: 10, done: false }
// generator-2
// { value: 20, done: false }
// generator-3
// { value: 'finished, done: true }
제너레이터 함수를 실행하면 제너레이터 객체만 반환 될 뿐, 함수 내부의 코드는 실행되지 않습니다.
next()를 호출하면 yield키워드를 만날 때까지 실행되고 데이터를 반환합니다.
그리고 더는 yield 키워드를 만나지 못하게 되면 객체의 done 속성값은 true가 됩니다.
다음은 return 메서드 입니다.
const gen = generator();
console.log(gen.next());
console.log(gen.return('abc'));
console.log(gen.next());
// generator-1
// { value: 10, done: false }
// { value: 'abc', done: true }
// { value: undefined, done: true }
return 메서드가 호출된 시점부터 done 속성값은 true로 바뀝니다.
마지막 throw 메서드 입니다.
function* generator() {
try {
console.log('generator-1');
yield 10;
console.log('generator-2');
yield 20;
} catch(e){
console.log('catch error', e);
}
}
const gen = generator();
console.log(gen.next());
console.log(gen.throw('에러 발생'));
// generator-1
// { value: 10, done: false }
// catch error 에러 발생
// { value: undefined, done: true }
throw 메서드를 호출하면 예외가 발생한 것으로 처리되기 때문에, catch문이 실행됩니다.
이때에도 done 속성값은 true가 됩니다.
제너레이터 객체는 반복 가능하면서 반복자이기도 합니다.
function* generator() {
yield 10;
yield 20;
yield 30;
}
for(const v of generator()){
console.log(v);
}
const arr = [...generator()];
console.log(arr);
// 10
// 20
// 30
// [10, 20, 30]
for of 문을 통해 반복 가능한 객체로 부터 반복자를 얻습니다.
그리고 반복자의 next()를 호출하면서 done의 속성값이 true가 될 때까지 반복합니다.
전개연산자 또한 done의 속성값이 true가 될 때까지 값을 펼쳐냅니다.
next()메서드를 이용하여 제너레이터 함수로 데이터를 전달하여 소비 시킬 수도 있습니다.
function* generator() {
const a = yield;
console.log(a);
const b = yield;
console.log(b);
}
const gen = generator();
gen.next(); // generator() 실행
gen.next(100); // a에 100 전달
gen.next(200); // b에 200 전달
// 100
// 200
이런식으로 활용을 해 볼 수도 있습니다.
'아카이브' 카테고리의 다른 글
200721 / TIL (0) | 2020.07.21 |
---|---|
200701 / TIL (0) | 2020.07.01 |
200630 / TIL (0) | 2020.06.30 |
200628 / TIL (0) | 2020.06.28 |
200627 / TIL (0) | 2020.06.27 |