holdanddeepdive / javascript-deep-dive

3 stars 1 forks source link

46장 제너레이터와 async/await #48

Open sbyeol3 opened 2 years ago

sbyeol3 commented 2 years ago

46장 제너레이터와 async/await

제너레이터란?

참고: async/await은 ES8에서 도입

제너레이터와 일반 함수의 차이

  1. 제너레이터 함수는 함수 호출자에게 함수 실행의 제어권을 양도할 수 있다.
    • 일반 함수에서 함수 호출자(caller)는 함수 호출 이후 함수 실행을 제어할 수 없지만 제너레이터 함수에서는 가능하다. 함수의 제어권을 함수가 독점하는 것이 아니라 함수 호출자에게 양도(yield)할 수 있다는 것을 의미한다.
  2. 제너레이터 함수는 함수 호출자와 함수의 상태를 주고받을 수 있다.
    • 일반 함수를 호출하면 실행 중에는 함수 외부에서 내부로 값을 전달하여 함수의 상태를 변경할 수 없다. 그러나 제너레이터는 함수 호출자와 양방향으로 함수의 상태를 주고 받을 수 있다.
  3. 제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.
    • 제너레이터 함수를 호출하면 함수 코드를 실행하는 것이 아니라 이터러블이면서 동시에 이터레이터인 제너레이터 객체를 반환한다.

제너레이터 함수의 정의

제너레이터 객체

function* genFunc() {
    yield 1;
    yield 2;
    yield 3;
}

const generator = genFunc()
console.log(Symbol.iterator in generator) // true
console.log('next' in generator) // true

console.log(generator.next()) // { value: 1, done: false } 
console.log(generator.next()) // { value: 2, done: false }
console.log(generator.return('END!')) // { value: 'END!', done: true }

제너레이터의 일시 중지와 재개

제너레이터의 활용

이터러블의 구현

// 무한 이터러블을 생성하는 함수
const infiniteFibonacci = (function () {
  let [pre, cur] = [0, 1]
  return {
    [Symbol.iterator]() {
      return this
    },
    next() {
      ;[pre, cur] = [cur, pre + cur]
      // 무한 이터러블이므로 done 생략
      return { value: cur }
    },
  }
})()

// infiniteFibonacci는 무한 이터러블
for (const num of infiniteFibonacci) {
  if (num > 10000) break
  console.log(num) // 1 2 3 5 8 13 21 ...
}
// 무한 이터러블을 생성하는 제너레이터 함수
const infiniteFibonacci = (function* () {
  let [pre, cur] = [0, 1]
  while (true) {
    ;[pre, cur] = [cur, pre + cur]
    yield cur
  }
})()

for (const num of infiniteFibonacci) {
  if (num > 10000) break
  console.log(num)
}

비동기 처리

const fetch = require('node-fetch')

const async = (generatorFunc) => {
  const generator = generatorFunc()

  const onResolved = (arg) => {
    const result = generator.next(arg)
    return result.done ? result.value : result.value.then((res) => onResolved(res))
  }

  return onResolved
}

async(function* fetchTodo() {
  const url = 'https://jsonplaceholder.typicode.com/todos/1'

  const response = yield fetch(url)
  const todo = yield response.json()
  console.log(todo)
})()

async/await

async 함수

await 키워드

에러 처리