제너레이터 함수(Generator Function)란?
제너레이터 함수(Generator Function)는 함수가 도중에 중간에 일시 중지한 다음 중지된 위치에서 로직이 실행되는 함수입니다.
자세한 사용 방법은 아래 링크를 클릭하여 게시된 포스팅을 확인해주세요.
☞ 제너레이터 함수(Generator Function) 이해하기
이번 포스팅에서는 제너레이터 함수를 실제로 응용 및 활용하는 방법에 대해 소개합니다.
반복자(Iterables) 구현
제너레이터는 반복 가능한 객체(iterable Object)이므로 반복자(iterator)를 구현할 수 있습니다.
다음은 반복자를 사용한 일반 함수입니다.
const iterableObj = {
[Symbol.iterator]() {
let step = 0;
return {
next() {
step++;
if (step === 1) {
return { value: 'Iterable : ' + step, done: false};
} else if (step === 2) {
return { value: 'Iterable : ' + step, done: false};
} else if (step === 3) {
return { value: 'Iterable : ' + step, done: false};
}
return { value: '', done: true };
}
}
},
}
for (const val of iterableObj) {
console.log(val);
}
실행 결과
다음은 제너레이터를 사용한 제너레이터 함수입니다.
function * iterableObj(step) {
yield 'Iterable : ' + step++;
yield 'Iterable : ' + step++;
yield 'Iterable : ' + step++;
}
for (const val of iterableObj(1)) {
console.log(val);
}
실행 결과
두 개의 예제를 비교해보면, 제너레이터 함수를 사용하는 방식이 코드가 더 간결하고 간단하다는 것을 알 수 있습니다.
제너레이터를 사용하여 반복자 구현의 이점
Symbol.iterator
을 작성할 필요가 없습니다.next()
함수를 구현할 필요가 없습니다.- 조건문을 작성할 필요가 없습니다. 일반 함수는 변수
step
마다 조건문이 존재하지만, 제너레이터 함수는 조건문이 필요 없습니다.
비동기 함수 구현
제너레이터는 Promise 작업을 단순화할 수 있습니다.
다음 예제는 Promise와 Callback을 사용하는 코드입니다.
function fetchJson (url) {
return fetch(url)
.then(request => request.text())
.then(text => {
return JSON.parse(text);
})
.catch(error => {
console.log (`에러 발생: ${error.stack}`);
});
}
위 예제는 제너레이터와 co.js 라이브러리를 사용하여 다음과 같이 동일하게 구현할 수 있습니다.
const fetchAPI = co.wrap(function* (url) {
try {
let request = yield fetch(url);
let text = yield request.text();
return JSON.parse(text);
}
catch (error) {
console.log('에러 발생 : ${error.stack}');
}
});
옵저버로 사용
제너레이터는 next(val)
함수를 사용하여 값을 받을 수도 있습니다. 즉, 제너레이터는 입력을 받을 때까지 모든 행동을 잠깐 중단하며, 새로운 값을 받을 때까지 관찰한다는 의미로 옵저버라고 할 수 있습니다.
일반적으로 옵저버는 세 가지 유형을 사용합니다.
next()
정상적인 입력을 보냅니다.return()
제너레이터를 종료합니다.throw()
오류를 나타냅니다.
다음은 옵저버 객체입니다.
const observer = {
next(value) {
console.log("next -> " + value + "");
},
error(err) {
console.log("에러 발생");
},
return() {
console.log("관측 종료");
}
}
다음은 옵저버 함수입니다.
function observable(observer) {
for(var i = 0; i <= 5; i++) {
observer.next(i);
}
observer.error();
observer.return();
}
실행 결과
옵저버 함수는 0에서 5까지 숫자를 순차적으로 방출하고 그다음에는 오류를 마지막으로 옵저버를 종료(관측 종료)합니다. 실제로 Observable 구현 방법은 위 예제처럼 간단하지 않으며, 약간 어려운 지식을 요구합니다.
옵저버는 위에서 언급했듯이 다음(next), 종료(return) 및 오류(throw)의 세가 지 유형이 존재합니다. 그리고 ES6 반복자(iterator)를 보면 next, throw 및 return 세 가지 함수가 존재합니다. 따라서 반복자를 반환하는 제너레이터를 만들 수 있습니다.
다음은 반복자를 반환하는 제너레이터 함수입니다.
function * observerGenerator() {
try {
while(true) {
let value = yield
console.log('next -> ' + value + '');
}
} catch (err) {
console.log('에러 발생') ;
}
console.log ('관측 종료');
}
다음은 반복자를 관찰자로 변환하는 함수를 정의합니다.
function createObserver(iterator) {
return {
next(value) { iterator.next(value) },
error(err) { iterator.throw(err) },
return() { iterator.return() }
}
}
다음은 옵저버 함수를 호출하여 관찰을 시작하는 코드입니다.
observable(createObserver(observerGenerator()));
실행 결과
실행 결과는 이전 예제와 동일합니다.
참조 사이트
https://medium.com/@swazza85/using-es6-generators-as-observers-3c8259d5785
'JavaScript > 함수' 카테고리의 다른 글
[JavaScript]생성자 함수(Constructor Function) (0) | 2021.12.13 |
---|---|
[JavaScript]call, apply, bind 함수 사용 방법 (1) | 2021.12.08 |
[JavaScript]제너레이터 함수(Generator Function) 사용 방법 (0) | 2021.12.05 |
[JavaScript]eval 함수의 문제점 (0) | 2021.12.04 |
[JavaScript]eval 함수 사용법 (0) | 2021.12.03 |
댓글