안녕하세요.
오늘은 Generator에 대해서 알아보도록 하겠습니다.
🔸 Generator란?
Generator는 함수의 실행을 중간에 멈췄다가 재개할 수 있는 함수입니다.
이때 컨텍스트는 저장된 상태로 남아 있습니다.
예제
Generator 함수는 호출되어도 즉시 실행되지 않고, 함수를 위한 Iterator 객체를 반환합니다.
function* idMaker() {
let index = 0;
while (index < 3) {
yield index++;
}
}
let iter = idMaker();
console.log(iter.next()); //{value: 0, done: false}
console.log(iter.next()); //{value: 1, done: false}
console.log(iter.next()); //{value: 2, done: false}
console.log(iter.next()); //{value: undefined, done: true}
Iterator의 next() 메서드를 호출하면 함수가 실행되어 yield 문을 만날 때까지 진행되고, iterator는 yield문이 반환할 값을 나타내는 value 속성과 마지막 yield문을 실행했는지 여부를 나타내는 done 속성을 리턴합니다.
🔸 메서드
next
yield 표현을 통해 yield 된 값을 반환합니다.
next 메서드에 인수를 전달하여 활용할 수 있습니다.
return
주어진 값을 반환하고 generator를 종료합니다.
(done 속성이 true로 세팅됩니다.)
throw
error를 throw하고 generator를 종료합니다.
(done 속성이 true로 세팅됩니다.)
🔸 특징
1. iterator 이면서 iterable 합니다.
iterable
- Symbol.iterator 메서드가 있습니다.
- Symbol.iterator는 iterator를 반환해야 합니다.
iterator
- next 메서드를 가집니다.
- next 메서드는 value와 done 속성을 가진 객체를 반환합니다.
- 작업이 끝나면 done은 true가 됩니다.
2. Lazy evalutaion
미리 값을 만들어두지 않고, 필요할 때 값을 요구하기 때문에 메모리를 효율적으로 사용할 수 있습니다.
function newArr(n) {
let i = 1;
const res = [];
while (i < n) {
console.log(i); // 1, 2, 3, 4, 5,...99
res.push(i++);
}
return res;
}
function* newArrGen(n) {
let i = 1;
while (i < n) {
console.log(i); // 1, 2, 3, 4, 5,...11
yield i++;
}
}
function fiveArr(iter) {
const res = [];
for (const item of iter) {
if (item % 5 == 0) res.push(item);
else if (res.length == 2) break;
}
return res;
}
console.log(fiveArr(newArr(100))); // fiveArr([1, 2, 3, 4... 99, 100]);
console.log(fiveArr(newArrGen(100)));
newArr는 즉시 배열을 만들어 내기 때문에 fiveArr 함수에 [1, 2, 3,... 99, 100]이 전달됩니다. 반면 newArrGen은 fiveArr 함수에 iterator만 전달합니다.
3. yield*로 다른 generator를 호출
function* gen1() {
yield 1;
yield* gen2();
yield 4;
}
function* gen2() {
yield 2;
yield 3;
}
const iter1 = gen1();
console.log(iter1.next()); //{value: 1, done: false}
console.log(iter1.next()); //{value: 2, done: false}
console.log(iter1.next()); //{value: 3, done: false}
console.log(iter1.next()); //{value: 4, done: false}
//전개 연산자를 사용해서 다음과 같이 호출할 수 있습니다.
console.log(...gen1()) // 1, 2, 3, 4
🔸 활용
- async/await
async/await은 generator와 promise를 활용하여 구현합니다.
비동기 처리가 끝나면 yield를 통해 제어권을 넘기고, 비동기 결과로 리턴된 promise의 then에서 재귀적으로 iterater.next를 호출하는 방식으로 구현됩니다.
(자세히 https://meetup.toast.com/posts/73)
- redux-saga
오늘은 Generator에 대해서 알아보았는데요, 틀린 것이 있거나 궁금한 것이 있으시면 댓글 부탁드립니다.
감사합니다.
출처
https://bbaktaeho-95.tistory.com/80
https://meetup.toast.com/posts/73
https://www.youtube.com/watch?v=qi24UqyJLgs
'Frontend > Javascript' 카테고리의 다른 글
[Javascript] Prototype 프로토타입 (0) | 2022.04.10 |
---|---|
[Javascript] Promise (0) | 2022.04.04 |
[Javascript] Garbage Collection (0) | 2022.03.22 |
[Javascript] Closure 클로저 (0) | 2022.03.17 |
[Javascript] this (0) | 2022.03.09 |