iterable 객체 및 yield 에 대해 이해하신 뒤 아래 내용을 읽어보시기 바랍니다.
yield: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/yield*
Generator function
generator function은 function* 로 정의한다. function 뒤에 별(*)을 붙여 generator라는 것을 지칭하며, 이 함수는 Generator 객체를 반환한다.
funtion* name([param[, param[, ...param]]]) {
/** ... */
}
generator function을 통해 할당받은 변수를 출력해 보면 Generator 타입임을 확인할 수 있다.
> function* gen() {
yield 1;
yield 2;
yield 3;
}
> let g = gen();
> g
gen {<suspended>}
__proto__: Generator
[[GeneratorStatus]]: "closed"
[[GeneratorFunction]]: ƒ* gen()
[[GeneratorReceiver]]: Window
[[GeneratorLocation]]: VM264:1
Generator
생성 방법
generator function의 반환으로 생성된 객체로 iterable 프로토콜과 iterator 프로토콜을 따르는 객체이다.
const generator = function* () {}
function* doSomething() {}
별(*)은 function 키워드와 괄호 사이에 넣으면 되므로 아래 방식도 유효하다.
const generator = function * () {}
const generator = function *() {}
function * doSomething() {}
function *doSomething() {}
Generator 객체 함수
function* gen() {
yield 1;
yield 2;
yield 3;
}
let g = gen(); // "Generator { }"
- Generator.prototype.next() : yield 를 통해 yield된 값을 반환
- Generator.prototype.return() : 주어진 값을 반환하고 생성기를 종료
- Generator.prototype.throw() : 생성기로 에러를 throw
예제, next() 함수의 결과
generator function 생성 방법은 *을 통해 간단하게 만들 수 있으므로 Generator 객체의 next() 함수 결과에 대해 알아보자.
const generatorFunction = function* () {
yield 1;
yield 2;
yield 3;
}
const generator = generatorFunction();
console.log(generator.next());
// {value: 1, done: false}
next() 를 처음으로 실행하 때, 첫 번째 yield가 발견되면 pause(정지)한다. 그리고 next() 를 계속해서 호출하면 아래와 같이 실행된다.
console.log(generator.next());
// {value: 2, done: false}
// -> next() 실행 후, 두번째 yield에서 정지
console.log(generator.next());
// {value: 3, done: false}
// -> next() 실행 후, 세번째 yield에서 정지
마지막으로 한번 더 호출하면…
console.log(generator.next());
// {value: undefined, done: true}
더이상 generator function 에서 보내줄 값이 없으니 value: undefined가 되고 iterable이 종료되어 done: true가 된다.
만약, 마지막 iteration이 실행될 때 value를 주고 싶다면 return 을 사용하면 된다.
const generatorFunction = function* () {
yield 1;
yield 2;
yield 3;
return 4;
}
위 예제와 동일하게 {value: 3, done: false} 까지 실행되고 next() 를 호출하면 {value: 4, done: true} 가 반환된다.
하지만, return 에서 전달한 값은 첫 번째 done: true일 때만 반환된다. 즉 아래와 같이 실행된다는 의미이다.
console.log(generator.next());
// {value: 1, done: false}
// -> next() 실행 후, 첫번째 yield에서 정지
console.log(generator.next());
// {value: 2, done: false}
// -> next() 실행 후, 두번째 yield에서 정지
console.log(generator.next());
// {value: 3, done: false}
// -> next() 실행 후, 세번째 yield에서 정지
console.log(generator.next());
// {value: 4, done: true}
// 계속 next()를 호출하면...
console.log(generator.next());
// {value: undefined, done: true}
console.log(generator.next());
// {value: undefined, done: true}
// ... 반복 ....
참고
- function* (MDN web docs, https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function*)
- ES2015(ES6) 반복기(iterator), 생성기(generator) (zerocho, https://www.zerocho.com/category/ECMAScript/post/579b34e3062e76a002648af5)
- JavaScript Iteration Protocols (Iterable and Iterator) and Generators (codeburst.io, https://codeburst.io/javascript-iteration-protocols-iterable-and-iterator-and-generators-bc0bf0bae3f6)
'JavaScript' 카테고리의 다른 글
[React-Native] console.error: "React Native version mismatch. (0) | 2019.08.29 |
---|---|
JavaScript 표준 (0) | 2018.09.13 |
form validate onsubmit (0) | 2018.07.25 |
JS 성능 비교 사이트 (0) | 2018.07.20 |
[JavsScript] XMLHttpRequest (0) | 2017.12.01 |
댓글