Generator function은 사용자가 원할 때 값을 꺼내올 수 있습니다.
실행을 잠시 멈췄다가 나중에 다시 접근할 수 있습니다.
즉 반복 가능한 iterator를 반환하며, 한번의 호출에 의해서 함수의 실행이 완료되지 않고 사용자의 요구에 따라 정지될 수도 있고 다시 시작될 수도 있습니다.
function * counter() {
yield 1
yield 2
yield 3
}
generator는 함수 앞에 *을 이용해서 사용합니다.
그리고 일반적인 함수에서는 값을 반환하기 위해서 return을 사용하는데 generator는 yield를 통해서 값을 반환합니다.
위 함수를 다음과 같이 실행시키면 어떤 결과가 나올까요??
const genObj = counter()
console.log(genObj.next())
console.log(genObj.next())
console.log(genObj.next())
실행 결과는 다음과 같습니다
1
2
3
generator를 실행하기 위해서는 next를 사용해서 실행합니다 1번 next를 실행할때마다 순차적으로 하나의 yield로 선언된 iterator들을 반환합니다.
즉 next로 한번 실행을 하면 첫 yield를 반환하고 멈춰있는 상태라고 생각을 하시면 됩니다.
Generator를 사용하는 장점은 크게 2가지가 있습니다.
우선 대용량의 데이터를 가공해서 다룬다고 한다고 했을때 기존 데이터를 배열에 올려서 사용한다고 하면 메모리가 많이 사용될 것입니다. 그런데 generator를 이용해서 하나씩 데이터를 불러온다면 메모리의 부담이 줄어드므로 메모리적으로 이득이 될 수 있습니다.
적은 데이터에서는 배열을 사용해서 아무 상관이 없지만 큰 데이터를 다룰때는 generator를 통하여 메모리 이득을 볼 수 있죠.
또 하나의 장점은 generator 코드를 작성한다고 바로 generator가 실행되지 않습니다. 무슨 말인지 잘 이해가 안될수도 있는데 코드를 통하여 살펴보도록 하겠습니다.
function *test() {
console.log('test')
yield 1
yield 2
}
const gen = test()
test라는 함수를 실행했으므로 당연히 test라는 출력 값이 실행될 것 같지만 실행이 되지 않습니다.
get.next()
next를 실행을 하고 나서야 test함수가 실행되어 test라는 출력 값이 나오게 됩니다.
즉 generator를 이용하면 어떤 값이 실제로 쓰일 때 까지 그 값의 계산을 뒤로 미루는 동작 방식을 구현할 수 있습니다.