[JavaScript] Gernerator

13717 단어 JavaScriptJavaScript

함수와 비슷한 형식의 문법을 기반으로 반복 가능한 객체를 생성

// 제너레이터 함수 선언문
function* count() {
  yield 1
  yield 2
  yield 3
  return 1
}
// 제너레이터 함수 표현식
const count = function* () {
  yield 1
  yield 2
  yield 3
  return 1
}

제너레이터 함수를 호출하면 코드가 실행되지 않고, 실행을 처리하는 특별 객체, 제너레이터 객체 반환
next()를 호출하면 가장 가까운 yield <value>문을 만날 때까지 실행하고 value반환

  • value: 산출 값
  • done: 함수가 종료 유무
generator = count() // [object Generator]
generator.next() // { value: 1, done: false }
generator.next() // { value: 2, done: false }
generator.next() // { value: 3, done: false }
generator.next() // { value: 1, done: true }
generator.next() // { value: undefined, done: true }

제너레이터는 iterable이여서 for..of 반복문을 사용해 값을 얻을 수 있다. 이때 return value는 무시된다.

for(const value of generator) {
  console.log(value) // 1 2 3
}

활용

배열 뒤집기

a = [1, 2, 3, 4, 5]
// 기본 방법
for(const value of a.reverse()){
  console.log(value)
}
// 제너레이터
function* reverse(array){
  for(let i = array.length -1; i>= 0; i--){
    yield array[i]
  }
}
for(const value of reverse(a)){
  console.log(value)
}

기본 방법은 동일한 크기의 배열을 하나 더 생성하나 제너레이터를 사용하면 그럴 필요가 없다.(메모리 절반 절약)

필터

// 기본 방법
for(const value of a.filter((x) => x > 2)){
  console.log(value)
}
// 제너레이터
function* filter(array, condition){
  for(const value of array){
    if(condition(value))
    	yield array[i]
  }
}
for(const value of filter(a, (x) => x > 2)){
  console.log(value)
}

무한수열

function* infinity() { 
  let i = 0; 
  while (true) 
    yield ++i;
}

비동기 처리

const fs = require("fs)

const generator = (function* () {
  const a = yield read(generator, "test_2.txt")
  console.log(a)
  const b = yield read(generator, "test_2.txt")
  console.log(b)
})()
generator.next() // 제너레이터 코드 실행을 위해 필수

function read(generator, filename){
  fs.readFile(filename, (error, data) => {
    generator.next(data)
  })
}

좋은 웹페이지 즐겨찾기