[TIL 24][JS] ES6 - 4

Mustache 🥸·2021년 4월 30일
0

Javascript

목록 보기
11/12

generator

  • generator는 function* 키워드를 사용한 함수이다.

형태

function* 선언문

  • function* 다음에 함수 이름 작성
function* sports(one, two){
  yield one + two;
}
console.log(typeof sports); // generator 함수 타입은 function
const obj = sports(1, 2);
console.log(typeof obj); // object
console.log(obj.next()); // iterator 오브젝트여서 next()가 가능
  • generator 함수를 호출하면 함수 블록 {} 을 실행하지 않고, generator 오브젝트를 생성하여 반환한다
  • generator 오브젝트는 iterator 오브젝트이다.

function* 표현식

  • function* 다음에 함수 이름 작성은 선택, 일반적으로 함수 이름을 작성하지는 않는다.
  • function* 왼쪽에 변수를 선언하며 변수 이름이 함수 이름이 된다.
  • 함수를 선언하는 형태만 다르고 function* 선언문과 같다.
const sports = function* (one){
  yield one;
}
const obj = sports(100);
console.log(obj.next()); {value: 100, done: false}

generatorFunction

  • GeneratorFunction.constructor을 사용하여 제네레이터 함수를 생성
  • 파라미터를 문자열로 작성, 마지막 파라미터가 함수 코드가 되고 앞은 파라미터 이름이 된다.
const fn = new Function("one", "return one");
console.log(fn(100)) // 100

// new 연산자를 사용하기 위해 constructor 할당
const create = Object.getPrototypeOf(function*(){}).constructor;

// 마지막 파라미터는 함수 코드가 된다
const sports = new create("one", "yield one");
const obj = sports(100);
console.log(obj.next()) // {value: 100, done: false}

메서드

return()

  • generatorObject.return()
  • return()의 파라미터 값을 리턴한다.
  • iterator를 종료시킨다.
function* sports(count){
  while(true){
    yield ++count;
  }
}
const obj = sports(10);
console.log(obj.next()) {value: 11, done: false}
console.log(obj.return(70)) // 이터레이터 종료 -> 파라미터 값 70을 리턴
console.log(obj.next(50)) // 이터레이터가 종료되어서 {value: undefined, done: true}
  • return()의 파라미터 값을 {value: 값, done: true}에서 value 프로퍼티 값으로 설정

throw()

  • generatorObject.throw()
  • {value: error message, done: true}를 리턴한다.
  • Error를 의도적으로 발생시킨다.
  • generator 함수의 catch()문에서 에러를 받는다.
function* sports(){
  try {
    yield 10;
  } catch (message){
    yield message;
  };
  yield 20;
}
const obj = sports();
console.log(obj.next()); // {value: 10, done: false}
console.log(obj.throw("error")); // {value: "error", done: false}
console.log(obj.next()); // {value: 20, done: false}
  • error가 발생했지만 iterator는 종료되지 않는다.

yield

function* sports(one){
  yield one + 10;
  yield;
  const value = yield one + 50;
}
const obj = sports(30);
console.log(obj.next()); // {value: 40, done: false}
console.log(obj.next()); // {value: undefined, done: false}
console.log(obj.next()); // {value: 80, done: false}
console.log(obj.next(200)); // {value: undefined, done: true}
  • yield는 next()로 호출될 때마다 하나씩 실행한다. (위 코드처럼) 전체가 실행되지 않고 next() 하나가 호출될때마다 리턴된다.
  • yield는 제네레이터 함수 실행을 멈추거나 다시 실행할 때 사용한다.
  • yield 오른쪽의 표현식을 평가하고 결과를 반환한다.
  • 표현식을 작성하지 않으면 undefined를 반환한다.
  • {value: , done: true/false} 반환한다.

키워드

value

  • yield 표현식의 평가 결과 설정
  • yield를 실행하지 못하면 undefined

done

  • yield를 실행하면 false
  • yield를 실행하지 못하면 true

yield의 사용의 예

yield의 반복

let status = true;
function* sports() {
  let count = 0;
  while(status){
    yield ++count;
  }
}
const obj = sports();
console.log(obj.next()) // {value: 1, done: false}
console.log(obj.next()) // {value: 2, done: false}
status = false;
console.log(obj.next()) // {value: undefined, done: true}

// status에 false를 함으로써 이터레이터 동작 제어

다수의 yield 처리

function* sports(){
  return yield yield yield;
}
const obj = sports();
console.log(obj.next())  // {value: undefiend, done: falase}
console.log(obj.next(10))// {value: 10, done: false}
console.log(obj.next(20))// {value: 20, done: false}
console.log(obj.next(30))// {value: 30, done: true}

// return 문을 작성하지 않으면 30이 아닌 {value: undefined, done: true} 반환

next()

  • next()는 yield 단위로 실행
  • yield 수만큼 next()를 작성해야 yield 전체가 실행된다.
function* sports(value){
  value += 20;
  const param = yield ++value;
  value = param + value;
  yield ++value;
}
const obj = sports(10);
console.log(obj.next()) // {value: 31, done:false} 2번째까지 실행됨
console.log(obj.next(20)) // {value: 52, done:false}
  • next()를 호출하면 이전 yield의 다음부터 yield까지 실행한다.

0개의 댓글