아래의 문제를 풀어보다가 검색을 통해 알아보았다.
제너레이터는 여러 개의 값을 필요에 따라 하나씩 반환할 수 있다.
문법 구조
제네레이터 함수는 function 뒤에 *를 붙여 표기한다 function*
function* thisIsGenerator(){
yield 1
yield 2
yield 3
return 19
}
일반 함수와 동작 방식이 다르며, 함수를 호출할 시 코드가 실행되는게 아니라 "제너레이터 객체"가 반환된다.
next()를 통해 값을 가져올 수 있는데, next() 메서드를 호출할 때 가장 가까운 yield문을 만날 때 까지 실행이 계속 된다. 이후 yield문을 만나면 멈추고 value값이 반환된다. next()는 항상 아래와 같은 형태의 객체를 반환한다.
{value:3, done:false}
value는 값이고, done은 함수의 코드실행이 끝났는지 안 끝났는지 boolean값으로 나타낸다.
function* generateSequence() {
yield 1;
yield 2;
return 3;
}
let generator = generateSequence();
let {value} = generator.next();
console.log(value)//1
제너레이터는 이터러블이기 때문에 for..of문을 사용할 수 있다.
위의 코드에 이어 쓴다면, 아래와 같이 사용할 수 있다.
for(let val of generator){
console.log(val)//1,2
}
다만, done이 true가 되는 return값은 출력되지 않는다.
출력하고 싶다면 for문에서 return대신 yield로 값을 반환해야한다.
또한 제너레이터는 이터러블이기때문에 spread 구문을 사용할 수 있다.
console.log([0, ...generateSequence()])// 0, 1, 2
주의해야 할 것은 변수 generator를 넣는게 아니라, 제너레이터함수 자체를 실행한 것을 사용해야한다. 아님 오류가 발생한다.
제너레이터 안에 제너레이터를 넣을 수 있는데, yield*를 사용하면 가능하다.
아래의 릿코드 문제에서 이와 같은 구조를 다루고 있는데, 아래와 같이 풀으면 된다.
// 내가 짠 코드
var inorderTraversal = function*(arr) {
for(let i=0;i<arr.length;i++){
if(Array.isArray(arr[i])){
yield* inorderTraversal(arr[i])
}else{
yield arr[i]
}
}
};
참고 링크
https://leetcode.com/problems/nested-array-generator
https://ko.javascript.info/generators
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Generator
'Today I learned! > 오늘 하루 배운 것, 기억할 것' 카테고리의 다른 글
[React] useImmer로 state 업데이트 하기 (0) | 2023.08.10 |
---|---|
[React] 모달 영역 밖 클릭 시 모달 닫히게 하기 (0) | 2023.08.02 |
[JS] "복사 방지" 구현 (0) | 2023.06.19 |
[JS]Array.prototype.at() (0) | 2023.05.24 |
[JS] Promise.race() (0) | 2023.05.10 |