JavaScript

Generator function

제너레이터 함수(Generator function)는 ES6에서 도입된 기능으로, 함수의 실행을 중간에 멈추고 재개할 수 있게 해주는 특별한 문법이다. 제너레이터는 비동기 처리를 동기적으로 표현할 수 있게 하며, 이터레이터와 밀접하게 연관되어 있다. 이를 통해 복잡한 비동기 로직을 쉽고 깔끔하게 관리할 수 있다.

제너레이터 함수의 사용 이유

  1. 비동기 코드를 동기적으로 표현: 제너레이터를 활용하면 비동기 처리를 순차적으로 실행하는 것처럼 코드를 작성할 수 있다. async/await도 내부적으로 제너레이터를 기반으로 작동한다.
  1. 이터레이터와 이터러블 쉽게 구현: 제너레이터는 이터레이터를 생성하는 간단한 방법을 제공한다. 이를 통해 반복 가능한 객체를 쉽게 만들 수 있다.
  1. 코루틴(Coroutine) 특성: 제너레이터 함수는 실행 중간에 멈출 수 있으며, 이를 통해 코루틴과 같은 효과를 낼 수 있다. 이는 동시성 프로그래밍을 구현하는 데 유용하다.
  1. 동시적 특성: 제너레이터는 여러 작업을 동시에 처리하는 흐름을 만들 수 있게 해준다.
  1. 비동기적 특성: 제너레이터는 비동기 처리를 간결하게 표현할 수 있게 해주며, 콜백 지옥을 피할 수 있다.
  1. 메모리 효율: 제너레이터는 필요할 때 값을 생성(yield)하기 때문에, 큰 데이터 세트를 작업할 때 메모리 사용을 최적화할 수 있다.

제너레이터 함수의 기본 문법

제너레이터 함수를 선언할 때는 함수 이름 뒤에 *를 붙인다. yield 키워드를 사용하여 함수의 실행을 중간에 멈출 수 있다.
function* generator() { yield 1; yield* [2, 3]; } const gen = generator();
제너레이터 객체에 .next() 메소드를 호출하면, yield에서 함수의 실행이 멈추고, { value: YIELDED_VALUE, done: BOOLEAN } 형태의 객체를 반환한다. done은 제너레이터 함수의 실행이 끝났는지 여부를 나타낸다.
console.log(gen.next()); // {value: 1, done: false} console.log(gen.next()); // {value: 2, done: false} console.log(gen.next()); // {value: 3, done: false} console.log(gen.next()); // {value: undefined, done: true}

무한 반복 예시

function* generator() { let i = 0; while (true) { yield i++; } } const gen = generator(); console.log(gen.next()); // {value: 0, done: false} console.log(gen.next()); // {value: 1, done: false} console.log(gen.next()); // {value: 2, done: false} // ...
제너레이터 함수는 무한 반복 로직에서도 유용하게 사용될 수 있으며, yield를 통해 필요한 시점에 반복을 멈추고 값을 반환할 수 있다. 이로 인해 메모리 사용을 최소화하고, 효율적인 반복 처리를 할 수 있게 된다.