제너레이터(generator)
제너레이터는 특이한 함수다.
함수 실행 중간에 멈출 수 있고, 재개할 수 있다. 그리고 멈출 때 값을 전달할 수도 있다.
제너레이터 함수를 정의하려면 function 키워드 뒤에 *를 입력하면 된다.
정의된 제너레이터 함수를 호출하면 제너레이터 객체를 반환한다.
이 때, 함수 내부 코드는 실행되지 않는다.
함수 내부 코드가 실행되지 않으니, 위 코드에서 '제너레이터 함수 내부'가 출력되지 않았다.
제너레이터 객체는 next, return, thorw 등의 메서드를 갖고 있다.
먼저 next를 사용해보자.
제너레이터 객체 메서드 - next
제너레이터 객체는 반복자(iterator)이기 때문에 next 메서드를 사용할 수 있다.
우선 제너레이터 객체를 정의하자.'
그리곤 next 메서드를 호출했다.
next 메서드를 호출하니 함수 내부 코드가 실행되었다.
실행 중인 함수는 yield 키워드를 만나면 멈춘다. yield 키워드는 제너레이터 함수내에서 사용 가능하다.
(yield의 뜻이 '내다'인 것을 보면 함수의 제어권을 우리에게 넘겨준다 이런 의미 같다.)
그리고 데이터 객체를 반환했다.
value는 yield 오른쪽에 있는 값인 123이고 done 속성은 false 이다.
next 메서드는 반복적으로 호출할 수 있다.
위 사진을 보면 yield를 만나 함수가 멈출 때 데이터 객체의 done은 false이고,
return을 만나 함수가 종료될 때 데이터 객체의 done은 true인 것을 확인할 수 있다.
그 후 next 메서드를 호출하면 value는 undefined이고 done은 true이다.
제너레이터 객체 메서드 - return
이번엔 return 메서드를 호출해보자.
위에서 next 메서드를 호출할 때랑 똑같이 제너레이터 객체를 정의하고 메서드를 호출했다.
done은 true, value는 인자인 데이터가 반환되었다.
그 후, next 메서드를 호출하면 undefined가 반환되었다.
제너레이터 객체 메서드 - throw
throw 메서드를 이용하면, 제너레이터 함수에서 예외 처리를 할 수있다.
try catch 문을 함수 내부에 사용하고, throw 메서드를 호출해보자.
throw 메서드를 호출하니 catch 문으로 들어갔다.
catch 안이나 try 안이나 똑같이 yield return 키워드를 사용할 수 있다.
반복자
next, return, throw 메서드를 호출하니 value와 done 속성을 가진 객체를 반환하였다.
이런 메서드를 사용할 수 있는 것은 제너레이터만의 고유한 특징이 아니라, 반복자의 공통된 특징이다.
반복자의 특징으론
- next 메서드를 갖고 있음
- next 메서드는 value와 done 속성값을 가진 객체를 반환함
- done 속성값은 작업이 끝났을 때 true가 됨
등이 있다.
제너레이터 객체도 반복자이기 때문에 위 특징들을 갖고 있다.
제너레이터 객체는 반복자일 뿐만 아니라 반복 가능한 객체(iterable)이다.
반복 가능한 객체의 특징으론
- Symbol.iterator 속성값으로 함수를 가지고 있음
- 해당 함수를 호출하면 반복자를 반환함
등이 있다.
제너레이터 객체에서 Symbol.iterator 함수를 호출한 결과는 제너레이터 객체(반복자) 자기 자신이다.
따라서 제너레이터 객체가 반복 가능한 객체임을 알 수 있다.
for of 문 & 제너레이터
제너레이터는 반복 가능한 객체이면서 반복자임으로 for of 문과 사용할 수 있다.
for of 문을 제너레이터 함수 안에 넣어서 활용할 수도 있다.
예시로 map 함수를 구현해보자.
function* map (iter, callback) {
for (const i of iter) {
yield callback(i)
}
}
const result = map([1, 2, 3, 4, 5], x => x * 2)
만든 함수를 실행시켰다.
앞서 제너레이터 함수를 호출하면 내부 코드를 실행하지 않고 제너레이터 객체를 반환한다고 했다.
그래서 result를 선언하면서 구현한 map 함수를 호출했을 때, 내부 코드는 실행되지 않았다.
이후 값이 필요한 순간에 연산이 시작되고 코드가 실행된다.
사실 제너레이터 함수를 활용하는 것은 복잡해보이고 불필요해 보일 수 있다.
하지만 제너레이터 함수는 여러 이점이 있다.
제너레이터 함수는 next 메서드를 호출하는 순간에 필요한 코드만 실행되니 연산을 줄일 수 있다.
이는 메모리 낭비, 시간 낭비를 줄여준다.
그리고 함수들 사이에서 멀티 태스킹을 할 수 있게 해주는 등 다양한 이점이 존재한다.
'프론트엔드 > 실전 리액트 프로그래밍' 카테고리의 다른 글
[스터디 with 실전 리액트 프로그래밍] 10편 - 가상돔 (0) | 2022.08.15 |
---|---|
[스터디 with 실전 리액트 프로그래밍] 9편 - UI 데이터 (0) | 2022.08.15 |
[스터디 with 실전 리액트 프로그래밍] 7편 - 프로미스 (0) | 2022.08.06 |
[스터디 with 실전 리액트 프로그래밍] 6편 - ES6+에서 객체와 배열 (0) | 2022.08.05 |
[스터디 with 실전 리액트 프로그래밍] 5편 - const, let, var (0) | 2022.08.05 |