본문으로 바로가기

 

[Generator란?]

Generator Function는 사용자의 요구에 따라 다른 시간 간격으로 여러 값을 반환할 수 있고 내부 상태도 관리할 수 있습니다. 단 한 번의 실행으로 함수의 끝까지 혹은 return까지 실행이 완료되는 일반 함수와는 달리, Generator 함수는 사용자의 요구에 따라 일시적으로 정지될 수도 있고, 다시 시작될 수도 있습니다. 또한 Generator 함수의 반환으로는 Generator가 반환됩니다.

 

함수에서 값을 여러 번에 걸쳐서 반환하는 것은 불가능합니다. 따라서 이 함수는 호출할 때마다 무조건 1을 반환하게 됩니다.

function returnFunc() {
  return 1;
  return 2;
  return 3;
  return 4;
  return 5;
}

 

하지만 제너레이터 함수를 사용하면 함수에서 값을 순차적으로 반환할 수 있습니다. 함수의 흐름을 도중에 일시 정지했다가 나중에 이어서 진행할 수도 있습니다. 제너레이터 함수를 만들 때는 function* 이라는 키워드를 사용합니다. 제너레이터 함수를 호출했을 때는 한 객체를 반환하게 되는데 이를 제너레이터라고 부릅니다.

function* generatorFunc() {
    console.log('Hello');
    yield 1;
    console.log('This is Generator');
    yield 2;
    console.log('Function*');
    yield 3;
    return 4;
}

// 제너레이터 생성
const generator = generatorFunc();

 

제너레이터 함수를 호출한다고 해서 해당 함수 안의 코드가 바로 시작되지는 않습니다. generator.next()를 호출해야만 코드가 실행되며, yield를 한 값을 반환하고 코드의 흐름을 멈춥니다. 코드의 흐름이 멈추고 나서 generator.next()를 다시 호출하면 흐름이 이어서 다시 시작됩니다.

 

제너레이터의 next()를 호출할 때 인자를 전달하여 이를 제너레이터 함수 내부에서 사용할 수도 있습니다.

function* sumGenerator() {
    console.log('start sumGenegerator');
    let a = yield;
    
    console.log('a값을 받았어요 -> ', a);
    let b = yield;

    console.log('b값을 받았어요 -> ', b);
    console.log('a+b = -> ', a+b);
    yield a+b;
}

 

 

[yield / next]

yield는 제너레이터 함수의 실행을 일시적으로 정지시키며, yield 뒤에 오는 표현식은 제너레이터의 caller에게 반환됩니다. 즉, 일반 함수의 return과 매우 유사하다고 볼 수 있습니다. 여기서 제너레이터 함수는 Callee이고, 이를 호출하는 함수가 Caller이며, Caller는 Callee의 yield 부분에서 다음 statement로 진행을 할지 여부를 제어합니다. 이는 next로 인해 재개될 수 있습니다.

 

그렇다면, 모든 yield를 처리하기 위해서는 그만큼 next를 사용해야 하는가 생각이 들 수 있습니다. 이것에 대한 답은 그럴수도 있고, 아닐 수도 있다는 것입니다. next를 일일이 호출하지 않고, 프로그래밍 방식으로 호출하게 하려면 재귀 호출을 하면 됩니다.

 

 

 

 

References

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

https://exploringjs.com/es6/ch_generators.html

https://react.vlpt.us/redux-middleware/10-redux-saga.html