처음 만난 리덕스 (Redux) 문서


12.2 Generator Function

redux-saga 라이브러리에서는, Saga를 구현하기 위해서 JavaScript의 Generator Function이라는 것을 사용합니다.
그래서 redux-saga에 대해서 배우기 전에, 먼저 이 Generator Function의 개념에 대해 정리를 하고 넘어가도록 하겠습니다.

Generator Function은 JavaScript의 버전 중 하나인 ES6에서 등장한 문법입니다.
해당 버전이 2015년에 나왔기 때문에 ECMAScript 2015라고 부르기도 합니다.
Generator Function은 function키워드 뒤에, 우리가 흔히 별표(*)라고 부르는 asterisk를 붙여서 사용합니다.
그리고 이 Generator Function 역시 Function. 즉, 함수이기 때문에 호출할 수 있으며, Generator Function을 호출하게 되면 Generator 객체를 리턴하게 됩니다.

Generator

여기서 많은 분들이 헷갈려 하는 부분이 Generator Function과 Generator입니다.

이름이 비슷해서 많이 헷갈릴 수 있는데, 위 그림처럼 Generator Function을 호출하면 Generator 객체가 생성됩니다.
그래서 Generator Function이라고 하면 함수를 의미하고, 그냥 Generator라고 하면 Generator Function을 호출해서 생성된 Generator 객체를 의미한다고 이해하면 됩니다.
이 부분은 앞으로도 종종 헷갈릴 수 있기 때문에 이해가 될 때까지 확실하게 개념을 정리하고 넘어가기 바랍니다.

ES6에서 이러한 Generator가 등장한 이유는 Iterator의 역할을 보완하기 위함입니다.
그래서 Generator의 역할에 대한 설명을 Iterator와 비교하면서 해보도록 하겠습니다.

먼저 Iterator는 반복하다는 뜻을 가진 영어 동사 Iterate로부터 파생되어 반복을 하는 주체를 나타내는 반복자라는 의미를 갖고 있습니다.
JavaScript에서 이 Iterator는 실행 순서를 정의하고 잠재적으로 종료 시 반환 값을 정의하는 객체입니다.
일반적인 Iterator는 코드 실행 순서를 중단할 수 없으며 중간에 끊김이 없이 지속적으로 코드를 실행합니다.

모든 Iterator에는 next()라는 함수가 있습니다.
이 함수를 호출하면 반복에 필요한 데이터가 들어있는 객체를 반환합니다.
이 객체에는 두 가지 값이 들어있는데 valuedone입니다.
value는 반복 순서의 다음 값을 의미하는 변수이고, done은 반복이 끝났는지 여부를 나타내는 boolean 변수입니다.

그리고 Generator는 Iterator의 한 종류인데, 지속적으로 끊김없이 코드를 실행하는 것이 아닌 원하는 시점에 코드를 실행할 수 있게 해줍니다.
다시 한 번 말씀드리면, Generator는 특별한 타입의 Iterator입니다.
그리고 Generator를 사용하면 코드 실행 흐름을 원하는대로 제어할 수 있다는 것이 일반적인 Iterator와의 차이점입니다.

그리고 그러한 흐름을 제어하기 위해서 사용하는 것이 바로 yield 키워드입니다.
yield는 Generator Function과 함께 사용하는 JavaScript의 키워드입니다.
yield는 사전적 의미로 어떠한 결과를 내다, 생산하다 라는 뜻을 갖고 있습니다.
단어의 의미와 비슷하게 JavaScript에서 yield 키워드가 해주는 역할은 Generator 객체로부터 결과를 산출해내는 것입니다.

Generator 역시 Iterator의 한 종류이기 때문에 Iterator가 가지는 next() 함수를 갖고 있습니다.
그래서 이 Generator가 갖고 있는 next() 함수를 호출하면, Generator 함수는 다음 yield 키워드를 만날 때까지 실행됩니다.

자, 사실 이런 이론적인 설명만으로는 아직 Generator Function과 yield의 역할이 잘 와닿지 않을 겁니다.
실제 Generator Function을 사용하는 예시 코드를 보면서 다시 설명해보도록 하겠습니다.

function* generatorFunction(num) {
    yield num;
    yield num + 10;
}

const generatorObject = generatorFunction(10);

// 출력 결과: 10
console.log(generatorObject.next().value);

// 출력 결과: 20
console.log(generatorObject.next().value);

먼저 위쪽에 generatorFunction이라는 이름의 Generator Function이 있습니다.
이 함수 내부에서는 yield 키워드를 총 2번 사용해서 파라미터로 받은 numbernumber + 10을 반환합니다.
yield라는 단어의 의미처럼 총 2번의 결과를 내는 것이죠.

generatorFunction() 함수를 호출하면 Generator. 즉, Generator 객체가 생성됩니다.
여기에서는 이해하기 편하도록 이 객체의 이름을 generatorObject라고 지었습니다.

앞에서 Generator 객체에는 next() 함수가 있다고 설명했었죠.
next() 함수를 호출하면 다음 yield를 만나기 전까지 코드가 실행됩니다.
그리고 처음 Generator 객체가 생성되는 시점에는 아무 코드도 실행되지 않습니다.

그래서 여기서 처음으로 next() 함수를 호출하면 파라미터로 넘긴 number의 값인 10이 출력됩니다.
그리고 이어서 다음으로 next() 함수를 호출하면 number에 10을 더한 값인 20이 출력됩니다.

Generator Function과 Generator 객체, 그리고 yield 키워드까지.
짧지만 이 코드를 통해서 실제 Generator가 작동하는 방식과 순서를 이해가 될 때까지 반복적으로 학습하기 바랍니다.
왜냐하면 redux-saga 라이브러리에서는 Saga를 구현하기 위해서 Generator를 사용하기 때문에, Generator에 대한 이해가 없는 상태로 넘어가게 되면 더 혼란스러울 수 있기 때문입니다.


마지막 업데이트: 2023년 07월 14일 00시 00분

이 문서의 저작권은 이인제(소플)에 있습니다. 무단 전재와 무단 복제를 금합니다.