[JavaScript ES6] Generator

Sooooooah·2023년 4월 25일

javaScript ES6

목록 보기
4/8

제너레이터란?

  • 여러 개의 값을 반환하는 함수 —> 함수 외부에서 실행되는 중간에 특정 부분에서 멈추고 값을 외부에서 받아 하나씩 반환
  • 특정 키워드(yield)에서 멈추었다가 필요한 시점에서 다시 재개

yield : 양도하다, (권한을) 넘겨주다 —> 함수 중간에서 실행을 멈추고, 제어권을 호출자에게 양도 → 호출자에 의해 다시 재개

function* testGen() {
  yield 1;
  yield 2;
  yield 3;
  return 4;
}

// 제너레이터 함수는 호출하면 바로 코드가 실행되는 것이 아니라 '이터레이터 객체'를 반환
// iterator 반복자 객체를 반환 --> 보통 it 또는 iter 라는 이름으로 받는다.

const iter = testGen();
// iterator 객체를 반환 > 이 객체는 next() 메서드가 실행될 때 마다, 처음 나오는 yield 부분까지 실행하고 멈춘다. (또는 제어권을 호출자에게 양도한다.)
// yield에서 멈췄을 떄, yield 뒤의 값(value)을 반환
// 만약 yield 뒤에 아무런 값이 없다면 --> undefined

console.log(iter.next()); // {value: 1, done: false}
console.log(iter.next()); // {value: 2, done: false}
console.log(iter.next()); // {value: 3, done: false}
console.log(iter.next()); // {value: 4, done: true}

Promise와 Generator 함수를 이용한 비동기 처리

1. 콜백 함수

// 1
setTimeout(
  (x) => {
    let result = x;
    console.log(result); // 10

    // 2
    setTimeout(
      (x) => {
        result *= x;
        console.log(result); // 200

        // 3
        setTimeout(
          (x) => {
            result *= x;
            console.log(result); // 6000

            // 4
            setTimeout(
              (x) => {
                result *= x;
                console.log(result); // 240000
              },
              1000,
              40
            );
          },
          1000,
          30
        );
      },
      1000,
      20
    );
  },
  1000,
  10
);

2. promise로 변환

1. new Promise() 호출하면 --> 대기(Pending) 상태
2. 이때, 콜백 함수를 선언할 수 있고 인자는 resolve, reject
3. 콜백 함수내에서 처리수행 --> resolve() 메서드를 호출 --> 이행(Fulfilled)상태
4. 성공이면 리턴값을 then()이 받아서 계속 처리 수행

new Promise((resolve, reject) => {
  setTimeout(
    (x) => {
      let result = x;
      console.log(result); // 10
    },
    1000,
    10
  );
})
  .then((result) => {
    return new Promise((resolve, reject) => {
      setTimeout(
        (x) => {
          result *= x;
          console.log(result); // 200
          resolve(result); // 200
        },
        1000,
        20
      );
    });
  })
  .then((result) => {
    return new Promise((resolve, reject) => {
      setTimeout(
        (x) => {
          result *= x;
          console.log(result); // 6000
          resolve(result);
        },
        1000,
        30
      );
    });
  })
  .then((result) => {
    return new Promise((resolve, reject) => {
      setTimeout(
        (x) => {
          result *= x;
          console.log(result); //240000
          resolve(result);
        },
        1000,
        40
      );
    });
  });

3. Generator로 변환

function* testGen() {
  const a = yield 1;
  console.log(a);
  const b = yield 1;
  console.log(b);
  const c = yield 1;
  console.log(c);
  const d = yield 1;
  console.log(d);
}

const iter = testGen();
iter.next();
// iter.next(); --> undefined
iter.next(101); // 101
iter.next(202); // 202
iter.next(303); // 303
iter.next(404); // 404

//-------------------------------------//

const calc = (x, y) => {
  setTimeout(() => {
    iter.next(x * y);
  }, 1000);
};
function* testGen() {
  const a = yield calc(1, 10); // 10
  console.log(a);
  const b = yield calc(a, 20); // 200
  console.log(b);
  const c = yield calc(b, 30); // 6000
  console.log(c);
  const d = yield calc(c, 40); // 240000
  console.log(d);
}

const iter = testGen();
iter.next();
profile
즐거운 서비스를 추구합니다.

0개의 댓글