[javascript] 제네레이터

자바스크립트에서 제네레이터는 이터레이터를 생성하는 함수입니다. 이터레이터는 값을 순회하고 소비할 수 있는 객체입니다. 제네레이터는 중단된 상태에서 실행을 일시 중지하고 나중에 다시 시작할 수 있는 독특한 기능을 제공합니다.

제네레이터 함수 정의하기

제네레이터 함수는 함수 선언과 유사하게 정의할 수 있습니다. 그러나 함수 이름 뒤에 별표(*)를 붙이는 것이 다릅니다.

function* generatorFunction() {
  // 제네레이터 함수의 본문
}

또는, 화살표 함수로 제네레이터 함수를 정의할 수도 있습니다.

const generatorFunction = function*() {
  // 제네레이터 함수의 본문
}

제네레이터 함수 안에서는 yield 키워드를 사용하여 값을 반환하고 실행을 일시 중지할 수 있습니다. yield로 반환된 값은 해당 제네레이터의 next() 메서드를 호출할 때까지 대기 상태에 머무릅니다.

제네레이터 사용하기

제네레이터 함수를 호출하면 제네레이터 객체가 반환됩니다. 제네레이터 객체는 next() 메서드를 가지고 있으며, 이 메서드를 호출하여 제네레이터 함수를 실행할 수 있습니다.

const generatorObject = generatorFunction();
const result = generatorObject.next();

next() 메서드가 호출되면, 제네레이터 함수의 실행이 시작되고 첫 번째 yield 표현식까지 실행됩니다. 이때 next() 메서드는 { value: 반환값, done: 완료 여부 } 형태의 객체를 반환합니다. 만약 yield 문이 더 이상 없을 경우, donetrue가 됩니다.

예제

이제 간단한 예제를 통해 제네레이터가 어떻게 동작하는지 살펴보겠습니다. 다음은 무한한 소수를 생성하는 제네레이터 함수의 예입니다.

function* infinitePrimes() {
  let number = 2;

  while (true) {
    if (isPrime(number)) {
      yield number;
    }
    number++;
  }
}

// 10개의 소수 출력하기
const generatorObject = infinitePrimes();
for (let i = 0; i < 10; i++) {
  const result = generatorObject.next();
  console.log(result.value);
}

function isPrime(number) {
  for (let i = 2; i < Math.floor(Math.sqrt(number)) + 1; i++) {
    if (number % i === 0) {
      return false;
    }
  }
  return number > 1;
}

위 예제에서 infinitePrimes() 제네레이터 함수는 무한한 소수를 생성합니다. yield 문을 통해 소수를 반환하고, next() 메서드를 호출하여 다음 소수를 생성하도록 합니다. isPrime() 함수는 주어진 숫자가 소수인지 확인하는 유틸리티 함수입니다.

이 예제를 실행하면 처음 10개의 소수가 출력됩니다. 제네레이터 함수가 무한히 반복할 수 있기 때문에, 필요한 만큼 소수를 생성할 수 있습니다.

정리

제네레이터는 자바스크립트에서 강력한 기능으로, 이터레이터를 생성하는 함수입니다. yield 키워드를 사용하여 값 반환 및 실행 일시 중지가 가능하며, next() 메서드를 통해 제네레이터 함수를 제어할 수 있습니다. 이를 통해 복잡한 비동기 코드를 간결하게 작성할 수 있습니다.

참고 자료