
๐ก ํจ์์ ์คํ์ ์ค๊ฐ์ ๋ฉ์ท๋ค๊ฐ ์ฌ๊ฐํ ์ ์๋ ๊ธฐ๋ฅ
function* fn1() {
    console.log(1);
    yield 1;
    console.log(2);
    yield 2;
    console.log(3);
    console.log(4);
    yield 3;
    return โfinishโ;
}
const a = fn1();
a.next(); // 1
fn1()ํจ์๋ฅผ ์คํํ๋ฉด generator ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.console.log(1)์ ์ฐํ์ง ์๋๋ค.next() ๋ฉ์๋๋ ๊ฐ์ฅ ๊ฐ๊น์ด yield ๋ฌธ์ ๋ง๋ ๋ ๊น์ง ์คํ๋๊ณ  ๋ฐ์ดํฐ ๊ฐ์ฒด ๋ฅผ ๋ฐํํ๋ค.value์ done ํ๋กํผํฐ๋ฅผ ๊ฐ์ง๋๋ฐ value๋ yield๋ฌธ์ ์ค๋ฅธ์ชฝ์ ์๋ ๊ฐ์ด๋ค.undefined๊ฐ ๋๋ค.done์ ์ด๋ฆ ๊ทธ๋๋ก ํจ์๊ฐ ์คํ๋๋์ง ํ๋จํ๋ฉฐ ํจ์๊ฐ ๋๋๋ฉด true, ์งํ์ค์ด๋ฉด false์ด๋ค.next() ๋ฉ์๋๋ฅผ ์คํํ๋ฉด value๋ undefined, done์ true๋ฅผ ๊ณ์ ๋ฐํํ๋ค.next()
return()
throw()
next(): ๋ค์ yield๋ฌธ์ ๋ง๋ ๋ ๊น์ง ์ฝ๋ ์คํretrun(): ํจ์ ์ค๊ฐ์ ํธ์ถํ๋ฉด ์ด ๋ฉ์๋์ ์ธ์๋ก ๋ฐ์ ๊ฐ์ value์ ๊ฐ์ผ๋ก done์ true๋ฅผ ๋ฐํํ๋ค.// return() ๋ฉ์๋ ์์
function* fn2() {
    console.log(1);
    yield 1;
    console.log(2);
    yield 2;
    console.log(3);
    console.log(4);
    yield 3;
    return โfinishโ;
}
const b = fn2();
const end = b.return(โENDโ);
console.log(end); // { value: โENDโ, done: true }
return() ๋ฉ์๋ ํธ์ถ ์ดํ์ next()๊ฐ ์คํ๋๋ value๋ฅผ ์ป์ ์ ์๊ณ  (undefined) done์ true์ด๋ค.throw(): ์คํ๋๋ฉด catch๋ฌธ์ ์์ฑ๋ ์์ธ์ฒ๋ฆฌ๋ฅผ ๋ฐํํ๋ค.// throw() ๋ฉ์๋ ์์
// 
์์ธ์ฒ๋ฆฌ๋ฅผ ์ํด tryโฆcatch ๋ฌธ์ ์ฌ์ฉ
function* fn2() {
    try{
      console.log(1);
      yield 1;
      console.log(2);
      yield 2;
      console.log(3);
      console.log(4);
      yield 3;
      return โfinishโ;
    } catch(e) {
         console.log(e);
    }
}
const b = fn2();
b.throw(new Error(โerrโ)); // err
err๋ฅผ ๋ฐํํ๊ณ  done์ true๊ฐ ๋๋ค.Symbol.iterator ๋ฉ์๋๊ฐ ์์ด์ผ ํ๋ค.Symbol.iterator๋ iterator๋ฅผ ๋ฐํํด์ผ ํ๋ค.next() ๋ฉ์๋๋ฅผ ๊ฐ์ง๋ค.next() ๋ฉ์๋๋ value์ done ์์ฑ์ ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.done์ true๊ฐ ๋๋ค.๐ generator๋ iterable ์ด๋ฉด์ iterator ์ด๋ค.
const arr = [ 1, 2, 3, 4, 5 ];
const it = arr[Symbol.iterator]();
console.log(it); // Object [Array Iterator] {}
console.log(it.next()); // 1
Symbol.iterator ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ  ์๊ณ  ์ด ๋ฉ์๋๊ฐ ๋ฐํํ๋ ๊ฐ์ด iterator ์ด๋ฏ๋ก iterableํ๋ค๊ณ  ํ  ์ ์๋ค.for (let num of arr) {
    console.log(num);
};
// 1
// 2
// 3
// 4
// 5
โผ๏ธ ๋ฌธ์์ด ๋ํ iterable ํ๊ธฐ ๋๋ฌธ์ for of ๋ฌธ์ผ๋ก ์์๊ฐ์ด ๋๋ฆฌ๋ฉด ๋์ผํ๊ฒ ๋์ํ๋ค.
function* fn3 () {
    const num1 = yield โ์ฒซ ๋ฒ์งธ ์ซ์๋ฅผ ์
๋ ฅํ์ธ์.โ;
    cosnole.log(num1);
    const num2 = yield โ๋ ๋ฒ์งธ ์ซ์๋ฅผ ์
๋ ฅํ์ธ์.โ;
    console.log(num2);
    return num1 + num2;
}
const d = fn3();
d.next(); // { value: โ์ฒซ ๋ฒ์งธ ์ซ์๋ฅผ ์
๋ ฅํ์ธ์.โ, done: false }
d.next(2); // 2, { value: โ๋ ๋ฒ์งธ ์ซ์๋ฅผ ์
๋ ฅํ์ธ์.โ, done: false }
console.log(d.next(4)); // 4, { value: 6, done: true }
d์ fn3()๋ฅผ ํ ๋นํ๊ณ  next() ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก ์ซ์๋ฅผ ์ ๋ฌํ๋ฉด num1 ๋ณ์์ value ๊ฐ์ ํ ๋นํ๋ค.yield๋ฌธ์ ๋ง๋๋ค ์ฌ๊ธฐ์๋ next() ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก ๊ฐ์ ์ฃผ๊ณ  ์ด๋ฅผ ์ฝ์๋ก ์ฐ์ด๋ณด๋ฉด num2๋ 4๊ฐ ํ ๋น๋๊ณ  return์ num1+num2์ ๊ฐ์ ๋ฐํํ๊ธฐ ๋๋ฌธ์ value๋6์ด๋ค.done์ true๋ก ๋ฐ๋๋ค.๐ Generator๋ ๊ฐ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋์ง ์๋๋ค.
๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์ธก๋ฉด์์ ํจ์จ์ ์ด๋ค.
ํ์ํ ์๊ฐ์๋ง ์ฐ์ฐํด์ ๊ฐ์ ์ค๋ค.
// ์์
function* fn4 () {
    let num = 0;
    while(true) {
        yield num++;
    }
}
const d = fn4();
console.log(d.next()); // 1
console.log(d.next()); // 2
console.log(d.next()); // 3 
function* gen1 () {
    yield โWโ;
    yield โoโ;
    yield โrโ;
    yield โlโ;
    yield โdโ;
}
function* gen2 () {
    yield โHello โ;
    yield* gen1();
    yield โ!โ;
}
console.log(โฆgen2()); // Hello, W o r l d !
โฆgen2() ์ฒ๋ผ ๊ตฌ์กฐ๋ถํดํ ๋น ์ ์ฌ์ฉํ ์ด์ : for of ์ ๋ง์ฐฌ๊ฐ์ง๋ก done์ด true๊ฐ ๋ ๋๊น์ง ํผ์ฒ์ฃผ๋ ์ญํ ์ ํ๋ค.โ๏ธ Generator ์ ๋ฆฌ
1. ์ ๋ค๋ ์ดํฐ๋ ๋ค๋ฅธ ์์ ์ ํ๋ค๊ฐ ๋์์์ next()๋ฅผ ํธ์ถ์ ์งํ์ด ๋ฉ์ท๋ ๋ถ๋ถ ๋ถํฐ ์ด์ด์ ์งํํ๋ค.
2. ๊ฐ์ ํ์ จ๋ ๋ถ์ Redux Saga์์ ์ฃผ๋ก ์ฌ์ฉํ๋ค๊ณ ํ๋ค.