ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Javascript] 제너레이터, generator
    웹/JavaScript 2023. 1. 13. 18:55

    제너레이터 generator

    function* genFunction () {
    console.log('하나를 반환합니다.');
    yield '하나';
    console.log('둘을 반환합니다.');
    yield '둘';
    console.log('셋을 반환합니다.');
    yield '셋';
    }
    const genFunc = genFunction();

     

    // 반복 수행해 볼 것
    // 💡 아래의 코드가 블록의 코드에 대한 제어권을 가짐
    console.log( genFunc.next() );
    • 함수 내 코드들을 모두 실행하지 않고 외부 호출자에게 제어권을 양도 - "계속할까요?"
    • 이터러블과 이터레이터를 보다 간결하게 구현 가능
    • 👉 MDN 문서 보기



    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,
    );




    2. 제너레이터 객체

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

     

    // 로그 펼쳐서 살펴볼 것
    console.log( genObj );

     

    // 💡 이터러블임 확인
    console.log( genObj[Symbol.iterator] );

     

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

     

    // ⚠️ 순회 후에는 재생성 필요
    console.log([...genObj]);

     

    // 이터러블로서는 바로 호출이 적합
    console.log([...genFunction()]);

     

    for (const num of genFunction()) {
    console.log(num);
    }

     

    genObj = genFunction(); // 재생성
    // 💡 이터레이터임 확인
    console.log( genObj.next );

     

    for (let i = 0; i < 7; i++) {
    console.log(genObj.next());
    }
    • ⭐ next 메서드를 실행하면 다음 yield까지 실행 후 중지
    • yield의 값을 value로 반환
    • 끝까지 실행 후 done: true




     

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

    예제 1. 🎲 주사위를 열 번 굴리는 제너레이터

    function* diceTenTimes () {
    let count = 0;
    const maxCount = 10;
    while (count++ < maxCount) {
    yield Math.ceil(Math.random() * 6);
    }
    }

     

    // 이터러블
    console.log(
    [...diceTenTimes()]
    );

     

    // 이터레이터 - 객체로 반환 뒤 사용
    // ⚠️ 다시 순회시 재생성 필요
    let diceGenObj = diceTenTimes();
    for (let i = 0; i < 12; i++) {
    console.log(diceGenObj.next());
    }




    예제 2. 🧮 피보나치 제너레이터

    function* fibonacci (maxCount) {
    let count = 0;
    let [x, y] = [0, 1];
    while (count++ < maxCount) {
    [x, y] = [y, x + y];
    yield y;
    }
    }

     

    console.log(
    [...fibonacci(10)]
    );

     

    let fiboGenObj = fibonacci(5);
    for (let i = 0; i < 7; i++) {
    console.log(
    fiboGenObj.next()
    );
    }




    예제 3. ⌛️ 순번 제너레이터

    function* workersGen (people) {
    let idx = 0;
    while (idx < people.length) {
    yield people[idx++];
    }
    }
    const team1 = [
    '철수', '영희', '돌준', '미나', '준희'
    ];

     

    console.log(
    [...workersGen(team1)]
    );

     

    // 이터레이터로 사용
    // 인원 순번 넘기기
    function switchWorker(iter) {
    const next = iter.next();
    console.log(
    next.done
    ? '-- 인원 없음 -- '
    : `${next.value} 차례입니다.`
    );
    }
    workersIter1 = workersGen(team1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
    switchWorker(workersIter1);
     
Designed by Tistory.