Generator 함수는 ES6에 도입된 이터러블을 생성하는 함수이다.
제네레이터를 사용하게 되면, 이터레이션 프로토콜을 준수해서 이터러블을 생성하는 방식보다 간편하게 이터러블이 구현 가능하다.
이는 비동기 처리에 유용하게 사용되곤 한다.
// Generator
// 이터레이션 프로토콜을 구현하여 무한 이터러블을 생성하는 함수
const createIteration = function () {
let i = 0; // 변수
return {
[Symbol.iterator]() {
return this;
},
next() {
return {value: ++i}
}
}
}
for (const n of createIteration()) {
if (n > 5) break;
console.log(n); // 1,2,3,4,5
}
제네레이터 함수는 일반 함수와는 다른 동작을 한다. 제네레이터 함수는 일반 함수와 같이 함수의 코드 블록을 한 번에 실행하지 않고 함수 코드 블록의 실행을 일시 중지했다가 필요한 시점에 재시작을 할 수 있는 함수이다.
비동기처리에서 사용하는 경우는 다음과 같다.
// async
const fetch = require('node-fetch');
function getUser(Obj, username) {
fetch(`https://api.github.com/users/${username}`)
// 제네레이터 객체에 비동기 처리 결과를 전달
.then(res => res.json())
.then(user => Obj.next(user.name));
}
// 제네레이터 객체 생성
const gene = (function* () {
let user;
// 비동기 처리 함수가 결과를 반환한다.
// 비동기 처리의 순서가 보장된다.
user = yield getUser(gene, 'Sunki');
console.log(user); // Kim Sunki
user = yield getUser(gene, 'Gilbert')
console.log(user); // Gilbert Jung
}());
// 제네레이터 함수 시작
gene.next()
비동기 처리가 완료되면 next 메소드를 통해 제네레이터 객체에 비동기 처리결과를 전달.
제네레이터 객체에 전달된 비동기 처리 결과는 user 변수에 할당.