본문 바로가기
JavaScript

[JavaScript] Generator

by 혀나Lee 2019. 1. 16.

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}
// ... 반복 ....

참고

'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

댓글