[TIL #11] JavaScript - Generator 란?

JMinkyoung·2021년 7월 17일
0

TIL

목록 보기
11/42
post-thumbnail

Generator는 ES6에 새롭게 도입된 개념이다. Generator는 함수이지만 함수와 다른 작동방식을 가지고 있다. 사실 JavaScript만을 따로 공부할 땐 들어본적이 없었는데 redux-saga를 배우면서 알게된 개념이라 한번 정리하고 넘어가는게 좋겠다고 생각했다 !

Generator 란?

일반 함수는 하나의 값(혹은 0개의 값)만을 반환합니다.
하지만 Generator를 사용하면 여러 개의 값을 필요에 따라 하나씩 반환 (yield) 할 수 있다.

기본 구조

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}

var g = gen(); // "Generator { }"

Generatorfunction*를 통해 정의된 Generator 함수를 호출하면 만들어지는 객체를 의미한다. 이러게 만들어진 객체는 Iterable이면서 Iterator 이기도 하다. 즉 Generator는 Iterator를 발생시키는 함수인 셈이다.


Iteralbe : 반복 가능한
Iterator : 반복자

예제

코드

function* gen() {
  yield 1;
  yield 2;
  yield 3;
}

let genn = gen(); // "Generator { }"
for(item of genn) console.log(item);

이 코드를 실행시키게 되면

결과

1
2
3

이렇게 배열들의 모든 요소를 출력 한 것 처럼 yield 옆의 표현식이 출력되었다.
이것이 의미하는 것은 yield 키워드가 Iterable의 요소가 된 것이다. 마치 배열처럼 yield 옆의 표현식이 배열의 요소가 되는 것이라고 생각이 가능하다 (실제 배열이 되는 것은 아니다)


코드

function* gen() {
  yield 1;
  yield 2;
  yield 3;
  return 100;
}

let genn = gen(); // "Generator { }"
console.log(genn.next());
console.log(genn.next());
console.log(genn.next());
console.log(genn.next());

yield 이외에 return에도 값을 설정해주고 앞에서 for문을 이용해서 출력했던것을 따르지 않고 Generator는 Iterator이기 때문에 next() 함수를 이용해서 값을 출력할 수 있으므로 사용했다. 이 코드를 실행시키게 되면

결과

{value: 1, done: false}
{value: 2, done: false}
{value: 3, done: false}
{value: 100, done: true}

결과를 살펴보면 yield를 통해 선언된 값들이 전부 출력되고 나서 return값이 출력되고 done: true로 바뀐 것을 확인할 수 있다.

start -> genn.next() -> yield 1 -> genn.next() -> yield 2 -> ... -> end

쓰는 이유?

Generator에 대한 개념을 찾아보고 예제들을 보고 가장 먼저 든 생각은 바로..
"그래서 Generator를.. 쓰는 이유가 뭔데...?😒"

무한루프 방지

function infinity() {
  let i = 0;
  while(true){
    return ++i;
  }
}
console.log(infinity());  // 1 출력
console.log(infinity());  // 1 출력
console.log(infinity());  // 1 출력

무한 루프를 통해 i값을 증가시키는 함수를 생성하고 출력하기 위해 console.log안에 넣으면 호출 할때마다 0에서 1만큼 증가한 1값만 계속해서 출력될 것이다.
만약 이를 Generator로 구현하게 되면 어떻게 될까?

function* infinity() {
  let i = 0; 
  while(true){
    yield ++i;
  }
}
// Generator 객체 생성
const gen = infinity();

console.log(gen.next().value);	// 1 출력
console.log(gen.next().value);  // 2 출력
console.log(gen.next().value);  // 3 출력

원했던 대로 정상적으로 출력되는 것을 확인할 수 있다. 우리가 원할때 gen을 공유한다면 언제 사용하던지 +1이 된 값을 받아서 사용이 가능하다는 장점이 있다. 또한 yield라는 중단점 때문에 무한루프에 빠지지 않는다.

비동기 처리

Generator 함수 내부에서 yield까지만 실행되는 원리를 이용하여 비동기 함수들을 순차적으로 실행이 가능하다.
하지만 이 방식은 잘 사용하진 않는다.. 왜냐하면.. async/await을 이용한 코드가 가독성이 좋기 때문에..

redux-saga를 다루기 위해 Generator에 대한 간단한 설명을 살펴보았는데.. 솔직히 왜 쓰는지 확 와닿지가 않아서 redux-saga에 대해 다룰때 느낄수 있길.. 🙏

profile
Frontend Developer

0개의 댓글