[Javascript] Generator 제너레이터 이해하기

데이빗·2024년 8월 22일

Javascript

목록 보기
13/13

Generator가 뭐임?

  • ES6 들어와서 새로 생김
    • 함수가 실행될 때의 흐름을 제어할 수 있는 방법론이며, 비동기 처리나 큰 데이터를 처리할 때 유용하게 쓸 수 있음.
  • 라고 말하면 이해가 안 되니 조금 더 쉽게 말하자면, 함수 내부의 로직들을, 함수 바깥에서 어디까지 실행하고 어디에서 멈출지를 정할 수 있다고 보면 됨.
    • 보통의 함수들은 호출 시 함수 내부에 정의되어 있는 모든 코드들을 처음부터 끝까지 실행시킴
    • 그러나 Generator는 함수 바깥에서 그걸 어디서 멈추고 어디서 재실행할지를 정할 수 있음.

어떻게 씀?

function* myGenerator() {
    yield 1;
    yield 2;
    yield 3;
}
  • 기본적으로 function 뒤에 *를 붙이면 generator가 됨.
  • 핵심 구문은 yield(산출) 임.
  • 그럼 이걸 .next()와 엮어서 쓰면 다음과 같이 됨.
const gen = myGenerator();

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 }

  • 이걸 보면,
    • 위에서 generator를 선언 시 1,2,3까지만 yield하게 되어 있었기 때문에, 1,2,3까지는 값이 반환이 되고, done이라는 key에는 false boolean값이 들어가 있음. 아직 yield할게 남아 있다는 거겠지.
    • 그리고 3까지 다 나오면 valueundefined가 되고, donetrue로 바뀜.
  • 최종적으로 이터레이션을 종료시키고 싶으면 그 때 return을 쓰면 됨.

비동기 처리할 때 쓰기

function* accumulateEveryTen() {
    let sum = 0;

    for (let i = 1; i < 1000; i++) {  // 루프
        sum += i;

        if (i % 10 === 0) {
            yield sum;  // 10번마다 합계를 yield
            sum = 0;    // 합계를 초기화
        }
    }
}

async function processGenerator(gen) {
    while (true) {
        for (let i = 0; i < 10; i++) {
            await new Promise(resolve => setTimeout(resolve, 100)); // 비동기 대기
        }
        const result = gen.next().value;
        console.log(result);
        if (result === undefined) break; // 종료 조건
    }
}

const gen = accumulateEveryTen();
processGenerator(gen);
  • 비동기 처리 시에도 활용이 가능한데...
    • 예를 들어 10개씩 더할 때마다 산출하는 코드 짜고 싶으면 i % 10을 사용하고 그 때만 yield sum.
  • 그리고 아래에 async로 함수를 하나 더 열어서, setTimeout으로 100ms마다 한 번씩 gen.next().value를 실행하면 됨.


출처1: https://ko.javascript.info/generators
출처2: https://wonism.github.io/javascript-generator/

profile
데이터 분석가

0개의 댓글