본문 바로가기
JavaScript 문법 시리즈

[JavaScript 문법] 32일차: 제너레이터

by cogito21_js 2024. 9. 2.
반응형

제너레이터란?

제너레이터(Generator)는 함수 실행을 일시 중지했다가 필요한 시점에 재개할 수 있는 특수한 유형의 함수입니다. 제너레이터 함수는 function* 키워드로 정의하며, yield 키워드를 사용하여 값을 반환하고 실행을 일시 중지할 수 있습니다.

제너레이터 함수

제너레이터 함수는 일반 함수와 달리 호출 시 즉시 실행되지 않고, 이터레이터 객체를 반환합니다. 이 이터레이터 객체의 next 메서드를 호출하면 제너레이터 함수가 실행됩니다.

기본 사용법

function* generatorFunction() {
  yield 'Hello';
  yield 'World';
}

const generator = generatorFunction();

console.log(generator.next().value); // 'Hello'
console.log(generator.next().value); // 'World'
console.log(generator.next().value); // undefined

yield 키워드

yield 키워드는 제너레이터 함수의 실행을 일시 중지하고, 호출자에게 값을 반환합니다. 다음 next 메서드를 호출하면 중지된 지점에서 실행이 재개됩니다.

예제

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

const counter = count();

console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
console.log(counter.next().value); // 3
console.log(counter.next().value); // undefined

next 메서드

next 메서드는 제너레이터 함수의 실행을 재개합니다. next 메서드는 { value, done } 객체를 반환합니다. 여기서 valueyield 표현식의 값이고, done은 제너레이터 함수가 끝났는지를 나타내는 불리언 값입니다.

예제

function* generatorFunction() {
  yield 'First';
  yield 'Second';
}

const generator = generatorFunction();

let result = generator.next();
while (!result.done) {
  console.log(result.value); // 'First', 'Second'
  result = generator.next();
}

제너레이터의 유용한 패턴

무한 시퀀스 생성

제너레이터는 무한 시퀀스를 생성하는 데 유용합니다.

function* infiniteSequence() {
  let i = 0;
  while (true) {
    yield i++;
  }
}

const sequence = infiniteSequence();

console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2

이터러블 구현

제너레이터를 사용하여 이터러블 객체를 쉽게 구현할 수 있습니다.

const iterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
};

for (const value of iterable) {
  console.log(value); // 1, 2, 3
}

비동기 작업 관리

제너레이터를 사용하여 비동기 작업의 흐름을 관리할 수 있습니다.

function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve('Fetched Data');
    }, 1000);
  });
}

function* asyncTask() {
  const data = yield fetchData();
  console.log(data);
}

const task = asyncTask();
const promise = task.next().value;

promise.then((data) => {
  task.next(data);
});

제너레이터의 장점과 단점

장점

  1. 코드 가독성 향상: 복잡한 반복 로직이나 비동기 작업을 간결하게 표현할 수 있습니다.
  2. 유연성: 필요에 따라 실행을 일시 중지하고 재개할 수 있습니다.
  3. 메모리 절약: 필요한 시점에 값을 생성하므로 메모리를 효율적으로 사용할 수 있습니다.

단점

  1. 디버깅 어려움: 제너레이터의 실행 흐름을 추적하고 디버깅하는 것이 어려울 수 있습니다.
  2. 익숙하지 않음: 제너레이터 문법이 익숙하지 않은 개발자에게는 이해하기 어려울 수 있습니다.

결론

제너레이터는 함수 실행을 일시 중지하고, 필요한 시점에 재개할 수 있는 강력한 도구입니다. 이번 글에서는 제너레이터 함수, yield 키워드, next 메서드의 기본 개념과 활용 패턴, 장점과 단점에 대해 배웠습니다. 다음 글에서는 Proxy와 Reflect에 대해 알아보겠습니다.

다음 글에서 만나요!

 

반응형