반응형
1. 제너레이터 함수?
ES6에 도입된 제너레이터(Generator) 함수는 이터러블을 생성하는 함수이다.
이전에 사용한 이터레이션 프로토콜을 준수해서 사용자 생성 방식보다 간단하게 이터러블을 구현할 수 있다.
또, 제너레이터 함수는 비동기 처리에 유용하게 사용된다.
function* gen() {
yield 1;
yield 2;
yield 3;
}
const genlter = gen();
console.log(genIter.next()); // {value:1, done: false}
console.log(genIter.next()); // {value:2, done: false}
console.log(genIter.next()); // {value:3, done: false}
console.log(genIter.next()); // {value:undefined, done: true}
제너레이터 함수는 일반적인 이터러블과 동일하게 동작하는 것처럼 보인다.
function* gen() {
console.log("첫 번째");
yield 1;
console.log("두 번째");
yield 2;
console.log("세 번째");
yield 3;
}
const genlter = gen();
console.log(genIter.next()); // 첫 번째 {value:1, done: false}
console.log(genIter.next()); // 두 번째 {value:2, done: false}
console.log(genIter.next()); // 세 번째 {value:3, done: false}
하지만 제너레이터 함수는 일반 함수와 같이 함수의 코드 블록을 한 번에 실행하지 않고 함수 코드 블록의 실행을
일시 중지했다가 필요한 시점에 재시작할 수 있는 특수한 함수이다.
즉, 제너레이터는 문장을 통해 순회할 수 있는 값을 만들 수 있으며, 어떤 값도 제너레이터를 통해 순회할 수 있는
형태로 조작할 수 있다.
2. 제너레이터 함수 정의
function* gen() {
yield 1;
yield 2;
yield 3;
return 100;
}
const genlter = gen();
console.log(genIter.next()); // {value:1, done: false}
console.log(genIter.next()); // {value:2, done: false}
console.log(genIter.next()); // {value:3, done: false}
console.log(genIter.next()); // {value:100, done: true}
제너레이터 함수의 선언은 funtion 앞에 *을 붙여서 function* 함수명 () {} 형식으로 선언하면 된다.
그리고 yield를 통해서 몇 번의 next()를 할지 결정할 수 있다.
return값을 설정하면 done이 true가 된 시점에 value 값을 리턴할 수 있다.
※ 하지만 기본적으로 순회하면서 조회할 때는 리턴값은 무시된다.
3. 제너레이터 함수 활용
제너레이터 함수를 사용해 간단하게 홀수만 계속 발생시키는 이터레이터를 만들어보자
function* odds(num) {
for(let i = 0; i < num; i++){
if(i % 2) yield i;
}
}
const genIter = odds(10);
console.log(genIter.next()); // {values : 1, done : false}
console.log(genIter.next()); // {values : 3, done : false}
console.log(genIter.next()); // {values : 5, done : false}
console.log(genIter.next()); // {values : 7, done : false}
console.log(genIter.next()); // {values : 9, done : false}
console.log(genIter.next()); // {values : undefined, done : true}
좀 더 심화시킨다면
function* infinity(i = 0) {
while(true) yield i++;
}
function* limit(num, iter){
for(const a of iter){
yield a; // --- 1
if(a === num) return;
}
}
function* odds(num) {
for(const a of limit(num, infinity(1))) {
if(a % 2) yield a;
}
}
1. 신기한? 부분이 limit을 호출하고 yield a; 라인까지 딱 실행된 다음에 다시 호출되면
아랫줄인 if(a === num) return 이 호출된 다음에 다시 for문이 실행된다.
반응형
'JavaScript' 카테고리의 다른 글
[JavaScript] ... 문법 (2) | 2022.06.11 |
---|---|
[JavaScript] 콜스택 (1) | 2022.06.04 |
[JavaScript] ES6에서의 순회와 이터러블 (2) | 2022.05.19 |
[JavaScript] 고차 함수 ( Higher-Order Function ) (2) | 2022.05.18 |
[JavaScript] 함수 ( 선언 ) 형 프로그래밍 (3) | 2022.05.17 |