logo
Search검색어를 포함하는 게시물들이 최신순으로 표시됩니다.
    Table of Contents
    [functional JS ES6+] generator와 iterator

    이미지 보기

    [functional JS ES6+] generator와 iterator

    • 22.06.03 작성

    • 읽는 데 3

    TOC

    generator

    • iterator이자, iterable을 생성(return)하는 함수
    • iter[Symbol.iterator]() == iter, 즉 자기 자신을 return하는 well-formed iterator
    function *gen() {
      yield 1;
      yield 2;
      yield 3;
      return 100;
    }
    
    let iter = gen();
    log(iter.next()); // {value: 1, done: false}
    log(iter.next()); // {value: 2, done: false}
    log(iter.next()); // {value: 3, done: false}
    log(iter.next()); // {value: return, done: true}
    
    for (const a of gen()) log(a); // 1 \n 2 \n 3
    
    • 일반 함수 앞에 '*' 표시를 붙여 만든다.
    • iterator이므로 next() method와 for of 문을 통한 순회도 가능
    • yield로 각 단계를 표시하고, return값은 done: true에 나오는 값

    yield는 문장도 가능

    yield 1;
    if (false) yield 2;
    yield 3;
    

    이는 곧 어떠한 값도 순회할 수 있는 객체로 만들 수 있다는 말


    generator의 활용

    홀수 generator: odds

    홀수만 뽑는 generator odds를 만든다

    function *adds(l) {
      for (let i=0; i<l; i++) {
        if (i % 2) yield i;
      }
    }
    let iter2 = odds(10);
    log(iter2.next()); // {value: 1, done: false}
    log(iter2.next()); // {value: 3, done: false}
    log(iter2.next()); // {value: 5, done: false}
    log(iter2.next()); // {value: 7, done: false}
    log(iter2.next()); // {value: 9, done: false}
    log(iter2.next()); // {value: undefined, done: true}
    log(iter2.next()); // {value: undefined, done: true}
    

    무한수열 generator: infinity

    function *infinity(i = 0) {
      while (true) yield i++;
    }
    
    let iter3 = infinity();
    iter3.next(); // {value: 1, done: false}
    iter3.next(); // {value: 2, done: false}
    iter3.next(); // {value: 3, done: false}
    iter3.next(); // {value: 4, done: false}
    
    • iterator의 next를 평가할 때까지만 동작하므로 while문에 따른 오류는 없다.

    여러 generator의 결합

    function *infinity(i = 0) {
      while (true) yield i++;
    }
    
    function *odds(l) {
      for (const a of infinity(1)) {
        if (a % 2) yield a;
        if (a == l) return;
      }
    }
    
    let iter2 = odds(10);
    log(iter2.next()); // {value: 1, done: false}
    log(iter2.next()); // {value: 3, done: false}
    ...
    log(iter2.next()); // {value: 9, done: false}
    log(iter2.next()); // {value: undefined, done: true}
    
    /////////////////////////////////////////////////////////////////
    
    function *limit(l, iter) {
      for (const a of iter) {
        yield a;
        if (a == l) return;
      }
    }
    
    let iter4 = limit(4, [1, 2, 3, 4, 5, 6]);
    log(iter4.next()); // {value: 1, done: false}
    log(iter4.next()); // {value: 2, done: false}
    log(iter4.next()); // {value: 3, done: false}
    log(iter4.next()); // {value: 4, done: false}
    log(iter4.next()); // {value: undefined, done: true}
    
    profile

    FE Developer 박승훈

    노력하는 자는 즐기는 자를 이길 수 없다