Generator

Yu Sang Minยท4์ผ ์ „
0

JavaScript

๋ชฉ๋ก ๋ณด๊ธฐ
48/48
post-thumbnail

๐Ÿ“Œ Generator

๐Ÿ’ก ํ•จ์ˆ˜์˜ ์‹คํ–‰์„ ์ค‘๊ฐ„์— ๋ฉˆ์ท„๋‹ค๊ฐ€ ์žฌ๊ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ

  • function ๋’ค์— โ€˜์—์Šคํ„ฐ ๋ฆฌ์Šคํฌ(*)โ€˜ ๋ถ™์—ฌ์„œ ์„ ์–ธ
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 ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰์‹œ generator ๊ฐ์ฒด๋งŒ ๋ฐ˜ํ™˜๋˜๊ณ  ๋ณธ๋ฌธ ์ฝ”๋“œ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  • ์‹ค์ œ๋กœ console.log(1)์€ ์ฐํžˆ์ง€ ์•Š๋Š”๋‹ค.
  • next() ๋ฉ”์„œ๋“œ๋Š” ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด yield ๋ฌธ์„ ๋งŒ๋‚ ๋•Œ ๊นŒ์ง€ ์‹คํ–‰๋˜๊ณ  ๋ฐ์ดํ„ฐ ๊ฐ์ฒด ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋Š” value์™€ done ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง€๋Š”๋ฐ value๋Š” yield๋ฌธ์˜ ์˜ค๋ฅธ์ชฝ์— ์žˆ๋Š” ๊ฐ’์ด๋‹ค.
  • ๋งŒ์•ฝ ๊ฐ’์„ ์ƒ๋žตํ•˜๋ฉด undefined๊ฐ€ ๋œ๋‹ค.
  • done์€ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋๋Š”์ง€ ํŒ๋‹จํ•˜๋ฉฐ ํ•จ์ˆ˜๊ฐ€ ๋๋‚˜๋ฉด true, ์ง„ํ–‰์ค‘์ด๋ฉด false์ด๋‹ค.
  • ํ•จ์ˆ˜๊ฐ€ ๋‹ค ๋๋‚˜๊ณ  next() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด value๋Š” undefined, done์€ true๋ฅผ ๊ณ„์† ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๐Ÿ“Œ Generator ๋ฉ”์„œ๋“œ

next()
return()
throw()
  1. next(): ๋‹ค์Œ yield๋ฌธ์„ ๋งŒ๋‚ ๋•Œ ๊นŒ์ง€ ์ฝ”๋“œ ์‹คํ–‰
  2. 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์ด๋‹ค.
  1. 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๊ฐ€ ๋œ๋‹ค.

๐Ÿ“Œ iterable๊ณผ iterator

  • iterable: ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์˜๋ฏธ
  • iterator: ์ด ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ

๐Ÿ“’ iterable์˜ ์กฐ๊ฑด

  1. Symbol.iterator ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
  2. Symbol.iterator๋Š” iterator๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“iterator

  1. next() ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง„๋‹ค.
  2. next() ๋ฉ”์„œ๋“œ๋Š” value์™€ done ์†์„ฑ์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  3. ์ž‘์—…์ด ๋๋‚˜๋ฉด 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 
  • next๋กœ ํ˜ธ์ถœ ํ• ๋•Œ ๋งˆ๋‹ค ๊ฐ’์„ ์ฃผ๊ธฐ ๋•Œ๋ฌธ
  • ์ผ๋ฐ˜์ ์ธ ํ•จ์ˆ˜๋กœ ๊ฐ’์„ ๊ตฌํ• ๋•Œ ๋ชจ๋“  ๊ฐ’์„ ๋ฏธ๋ฆฌ ๊ณ„์‚ฐํ•ด ๋†”์•ผ ํ•œ๋‹ค.
  • ์“ธ์ง€ ์•ˆ์“ธ์ง€ ์ •ํ•ด์ง€์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ๋„ ๊ทธ ๊ฐ’์„ ์œ ์ง€ ํ•ด์•ผํ•œ๋‹ค.
  • generator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ์ˆœ๊ฐ„๊นŒ์ง€ ๊ณ„์‚ฐ์„ ๋ฏธ๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ“Œ generator๋ฅผ ๋‹ค๋ฅธ generator ํ•จ์ˆ˜์—์„œ ํ˜ธ์ถœํ•˜๊ธฐ

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๊ฐ€ ๋ ๋•Œ๊นŒ์ง€ ํŽผ์ฒ˜์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.
  • yield* ์˜ค๋ฅธ์ชฝ์—๋Š” generator ๊ฐ์ฒด๊ฐ€ ์™”๋Š”๋ฐ, ์‚ฌ์‹ค ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ ์˜ฌ ์ˆ˜ ์žˆ๋‹ค.

โœ’๏ธ Generator ์ •๋ฆฌ
1. ์ œ๋„ค๋ ˆ์ดํ„ฐ๋Š” ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๋‹ค๊ฐ€ ๋Œ์•„์™€์„œ next()๋ฅผ ํ˜ธ์ถœ์‹œ ์ง„ํ–‰์ด ๋ฉˆ์ท„๋˜ ๋ถ€๋ถ„ ๋ถ€ํ„ฐ ์ด์–ด์„œ ์ง„ํ–‰ํ•œ๋‹ค.
2. ๊ฐ•์˜ ํ•˜์…จ๋˜ ๋ถ„์€ Redux Saga์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

profile
ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž ์ง€๋ง์ƒ (React, Node.js, AWS, Git, Github, Github Action, Docker)

0๊ฐœ์˜ ๋Œ“๊ธ€

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด