
제너레이터는 다른 작업을 하다가 다시 돌아와서
next() 해주면 진행이 멈췄던 부분 부터 이어서 실행
함수의 실행을 중간에 멈췄다가 제개할 수 있는 기능
yield 키워드에서 함수 실행을 멈출 수 있음
예제
function* fn(){
yield 1;
yield 2;
yield 3;
return "finish";
}
const a = fn();
console.log(a)
가장 가까운 yield문까지 실행되고 데이터 객체를 반환
function* fn(){
console.log(1);
yield 1;
console.log(2);
yield 2;
console.log(3);
console.log(4);
yield 3;
return "finish";
}
const a = fn();
console.log(a.next())
💻출력값
1
{ value: 1, done: false }
반환된 객체에는 value와 done 프로퍼티를 갖는다
value : yield 오른쪽 값
done : 함수 코드의 끝남 유무
(끝났으면 true, 중간에 멈추면 false)
done 값을 true로 변경
이후의 done 값도 true로 변함
console.log(a.return("END"))
console.log(a.next())
//출력
{ value: 'END', done: true }
{ value: undefined, done: true }
done 값을 true로 변경
function* fn(){
try {
console.log(1);
yield 1;
console.log(2);
yield 2;
console.log(3);
console.log(4);
yield 3;
return "finish";
} catch (e) {
console.log(e);
}
}
const a = fn();
console.log(a.next())
console.log(a.next())
console.log(a.throw(new Error("err")))
console.log(a.next())
//출력
1
{ value: 1, done: false }
2
{ value: 2, done: false }
Error: err
{ value: undefined, done: true }
{ value: undefined, done: true }
💡Generator는 Iterator 이면서 Iterable 이다
반복이 가능하다는 뜻
조건
Symbol.iterator 메서드가 있다
Symbol.iterator 는 iterator 를 반환해야한다.
next 메서드를 가진다
next 메서드는 value 와 done 속성을 가진 객체를 반환한다.
작업이 끝나면 done은 true가 된다.
💡배열은 Symbol.iterator를 가지고 있다
const arr = [1, 2, 3, 4, 5];
const it = arr[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
//출력
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }
{ value: 5, done: false }
{ value: undefined, done: true }
function* fn() {
const num1 = yield "첫번째 숫자를 입력해주세요";
console.log(num1);
const num2 = yield "두번째 숫자를 입력해주세요";
console.log(num2);
return num1 + num2;
}
const a = fn();
console.log(a.next())
console.log(a.next(2))
console.log(a.next(4))
//출력
{ value: '첫번째 숫자를 입력해주세요', done: false }
2
{ value: '두번째 숫자를 입력해주세요', done: false }
4
{ value: 6, done: true }
💡메모리관리 측면에서 효율적
필요한 순간까지 미룰 수 있음
function* fn() {
let index = 0;
while(true){
yield index++;
}
}
const a = fn();
console.log(a.next())
console.log(a.next())
console.log(a.next())
console.log(a.next())
console.log(a.next())
console.log(a.next())
//출력
{ value: 0, done: false }
{ value: 1, done: false }
{ value: 2, done: false }
{ value: 3, done: false }
{ value: 4, done: false }
{ value: 5, done: false }
function* gen1(){
yield "W";
yield "o";
yield "r";
yield "l";
yield "d";
}
function* gen2(){
yield "Hello,";
yield* gen1();
yield "!";
}
//구조 분해 할당
console.log(...gen2());
//출력
Hello, W o r l d !
💡yeild* 뒤에는 반복가능한 모든 객체가 올 수 있다.