ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Section 10. 자바스크립트 제너레이터
    자바스크립트 2023. 4. 7. 12:27

    제너레이터의 특징은 다음과 같다

    • 함수 내 코드들을 모두 실행하지 않고 외부 호출자에게 제어권을 양도한다. - "계속할까요?"
    • 이터러블과 이터레이터를 보다 간결하게 구현 가능하다.
    function* genFunction () {
      console.log('하나를 반환합니다.');
      yield '하나';
    
      console.log('둘을 반환합니다.');
      yield '둘';
    
      console.log('셋을 반환합니다.');
      yield '셋';
    }
    
    const genFunc = genFunction();
    
    // 반복 수행해 볼 것
    // 💡 아래의 코드가 블록의 코드에 대한 제어권을 가짐
    console.log( genFunc.next() );
    //하나를 반환합니다.
    //{value: '하나', done: false}

     

    I. 기본 사용법

    1. 제너레이터 함수 / 메서드 선언

    function 다음 또는 메서드명 앞에 * 를 붙인다. 띄어쓰기 위치는 무관하다.

    // 함수 선언
    function* genFunc1 () {
      yield 'genFunc1';
    }
    // 값으로 대입
    const genFunc2 = function* () {
      yield 'genFunc2';
    }
    // 객체의 메서드
    const obj = {
      * genFunc3 () {
        yield 'genFunc3';
      }
    }
    // 클래스의 메서드
    class MyClass {
      * genFunc4 () {
        yield 'genFunc4';
      }
    }

    이런식으로 선언을 하고 출력하면 다음과 같다

    // 테스트
    console.log(
      genFunc1().next().value,
      genFunc2().next().value,
      obj.genFunc3().next().value,
      new MyClass().genFunc4().next().value,
    ); //genFunc1 genFunc2 genFunc3 genFunc4

    *yield?

    일반적인 함수에서는 return문으로 return값을 써주지만 제너레이터에서는 return대신 yield를 쓴다. 

    yield 'genFunc1'; 하면 genFunc1을 리턴값으로 넘기겠다는 뜻이 된다.

     

    2. 제너레이터 객체

    • 제너레이터 함수의 결과값으로 반환된다.
    • 이터레이터이자 이터러블이다.
    function* genFunction () {
      yield 1;
      yield 2;
      yield 3;
      yield 4;
      yield 5;
    }
    
    let genObj = genFunction();

    제너레이터 함수 genFunction의 결과값인 genObj가 있다. genObj는 제너레이터 객체이다.

    제너레이터 객체는 next도 있고 심볼 이터레이터도 있다. 즉, 제너레이터 객체는 이터러블과 이터레이터의 기능을 기반으로 만들어져 있다는 것을 알 수 있다. 

     

    순회 후에는 재생성이 필요하다.

    console.log([...genObj]); //[]

    따라서 이터러블로서는 바로 호출이 적합하다.

    console.log([...genFunction()]); //[1, 2, 3, 4, 5]

     

    다시한번 정리하자면 다음과 같다

    • next 메서드를 실행하면 다음 yield까지 실행 후 중지
    • yield의 값을 value로 반환
    • 끝까지 실행 후 done : true

    II. 이터러블과 이터레이터 대체하기

    이터러블 정리에서 했었던 주사위 굴리는 예제를 제너레이터를 사용하여 엄청 간단하게 만들 수 있다.

     

    주사위를 열 번 굴리는 제너레이터

    function* diceTenTimes () {
      let count = 0;
      const maxCount = 10;
    
      while (count++ < maxCount) {
        yield Math.ceil(Math.random() * 6);
      }
    }
    // 이터러블
    console.log(
      [...diceTenTimes()]
    ); //[1, 5, 4, 1, 2, 1, 4, 3, 5, 3]
    // 이터레이터 - 객체로 반환 뒤 사용
    // ⚠️ 다시 순회시 재생성 필요
    let diceGenObj = diceTenTimes();
    
    for (let i = 0; i < 12; i++) {
      console.log(diceGenObj.next());
    }

     

Designed by Tistory.