[React다루는기술] 23. redux-saga에 앞서 제너레이터 함수(generator function)
in React on React 다루는 기술
React 에서 redux-saga 의 비동기 작업을 하기 전에 제너레이터 함수에 대한 포스팅이다. 제너레이터 함수(generator function)는 일반 함수와는 다르게 실행 중간에 멈출 수 있고, 필요할 때 다시 시작할 수 있는 함수
입니다. 제너레이터 함수는 함수 내부에 yield 키워드를 사용하여 값을 반환하고 함수 실행을 일시 중지시킬 수 있다.
1. 제너레이터 함수 function*
일반 함수는 하나의 값(혹은 0개의 값)만을 반환하지만 제너레이터(generator)를 사용하면 여러 개의 값을 필요에 따라 하나씩 반환(yield)할 수 있습니다. 제너레이터와 이터러블 객체를 함께 사용하면 손쉽게 데이터 스트림을 만들 수 있다. 여기서 yield는 ‘생산하다, 산출하다’라는 의미이다.
제너레이터를 만들려면 ‘제너레이터 함수’라 불리는 특별한 문법 구조, function*
으로 함수를 선언한다.
제너레이터 함수는 일반 함수와 동작 방식이 다릅니다. 제너레이터 함수를 호출하면 코드가 실행되지 않고, 대신 실행을 처리하는 특별 객체, 제너레이터 객체
가 반환됩니다.
function* generatorFunction() {
yield 1;
yield 2;
yield 3;
}
// '제너레이터 함수'는 '제너레이터 객체'를 생성합니다.
let generator = generatorFunction();
alert(generator); // [object Generator]
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }
next()는 제너레이터의 주요 메서드로 next()를 호출하면 가장 가까운 yield <value>문을 만날 때까지 실행이 지속
된다. yield
- value: 산출 값
- done: 함수 코드 실행이 끝났으면 true, 아니라면 false
제너레이터 다른 예제
function* generatorFunction(x, y) {
yield x + y;
yield x - y;
}
const generator = generatorFunction(5, 3);
console.log(generator.next()); // { value: 8, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: undefined, done: true }
function* generatorFunction(x, y) {
yield x + y;
yield x - y;
yield x * y;
return 9;
}
//제너레이터와 이터러블
const generator = generatorFunction(11, 4);
for(let value of generator) {
console.log(value); // 15, 7, 44
}
function* generatorFunction(a) {
console.log('# a = ', a)
let b = yield;
console.log('# b = ', b)
yield a + b;
let c = yield;
console.log('# c = ', c)
yield a + b + c;
}
const generator = generatorFunction(10);
console.log(generator.next())
console.log(generator.next(2))
console.log(generator.next())
console.log(generator.next(4))
# a = 10
(2) {value: undefined, done: false}
# b = 2
(2) {value: 12, done: false}
(2) {value: undefined, done: false}
# c = 4
(2) {value: 16, done: false}
function* fibonacciGenerator(a, b) {
while (true) {
//console.log(a, b)
yield a;
[a, b] = [b, a + b];
}
}
// 피보나치 수열의 첫 10개 숫자 출력
const fibonacciSequence = fibonacciGenerator(0, 1);
for (let i = 0; i < 10; i++) {
console.log(fibonacciSequence.next().value);
}