generator

함수의 실행을 중간에 멈췄다가 제개할 수 있는 기능

  1. function 옆에 *을 사용해서 만들 수 있다.
  2. yield에서 함수의 실행을 멈출 수 있다.
  3. generator함수를 실행하면 generator 객체가 반환된다.
  4. generator객체는 next 메소드가 있다.
function* fn() {
  console.log(1);
  yield 1;
  console.log(2);
  yield 2;
  console.log(3);
  console.log(4);
  yield 3;
  return "finish";
}

const a = fn(); // fn{<suspended>}
a.next(); // 1 // {value: 1, done: false}
a.next();
a.next(); // 3, 4 / {value: 3, done: false}
a.next(); // {value: "finish", done: ture}
a.next(); // {value: undefined, done: ture}

a.next를 사용하면 가장 가까운 yield 문이 나올 때까지 실행되고 데이터 객체를 반환한다.
value는 yield 오른쪽 값, 생략하면 undefined
done은 함수 코드가 끝났는지 나타내며 실행이 끝났으면 true 아니면 false를 반환힌다.



return()

next 메소드를 실행하다가 return 메소드를 실행하면 그 즉시 done: true를 반환한다.

function* fn() {
  console.log(1);
  yield 1;
  console.log(2);
  yield 2;
  console.log(3);
  console.log(4);
  yield 3;
  return "finish";
}

const a = fn();
a.next(); // 1
a.return("END"); // {value: 'END', done: true}


throw()

throw 역시 done을 즉시 true로 반환하게 한다.

function* fn() {
  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 a = fn();
a.next(); // 1
a.throw(new Error("err")); // Error: err / {value: undefined, done: true}

throw는 catch문을 실행시켜서 Error를 반환한다.



iterable

  • generator는 iterable이다.
  • iterable(반복이 가능하다)
  • Symbol.iterator 메소드가 있다.
  • Symbol.iterator 메소드로 구현된 결과는 iterator라고 한다.
iterator
  • next 메소드를 가진다.
  • next 메소드는 value와 done 속성을 가진 객체를 반환한다.
  • 작업이 끝나면 done은 true가 된다.
  • generator는 iterable이면서 iterator이다.
  • 배열 역시 iterable이다.(프로토에서 Symbol.iterator 확인 가능)


배열 예문
const arr = [1, 2, 3, 4, 5];
const it = arr[Symbol.iterator]();
console.log(it.next()); // {value: 1, done: false}
console.log(it.next()); // {value: 2, done: false}
console.log(it.next()); // {value: 3, done: false}
console.log(it.next()); // {value: 4, done: false}
console.log(it.next()); // {value: 5, done: false}
console.log(it.next()); // {value: undefined, done: true}
iterable은 for of로 순회가 가능하다.
function* fd() {
  yield 1;
  yield 2;
  yield 3;
}

const d = fd();
console.log(d[Symbol.iterator]() === d);

generator에 [Symbol.iterator] 값이 자기 자신이라는 것을 의미한다.
즉, generator는 iterable 객체인 것이다. 순회 가능


배열 순회
const arr = [1, 2, 3, 4, 5];
const it = arr[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

for (let num of arr) {
  console.log(num); // 1 / 2 / 3 / 4 / 5 /
}


문자열 순회
const str = "hello";
console.log(str[Symbol.iterator]); // ƒ [Symbol.iterator]() { [native code] }

const xx = str[Symbol.iterator]();
console.log(xx.next()); // {value: 'h', done: false}
console.log(xx.next()); // {value: 'e', done: false}

for (let s of xx) {
  console.log(s);
} // l / l / o - next로 나온 값 다음부터 순회가 된다.

댓글남기기