언젠간 진화하겠지!

[JS]제너레이터 본문

Today I learned!/오늘 하루 배운 것, 기억할 것

[JS]제너레이터

sweeee 2023. 6. 25. 21:45

아래의 문제를 풀어보다가 검색을 통해 알아보았다.

제너레이터는 여러 개의 값을 필요에 따라 하나씩 반환할 수 있다.

 

문법 구조

제네레이터 함수는 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

 

Nested Array Generator - LeetCode

Can you solve this real interview question? Nested Array Generator - Given a multi-dimensional array of integers, return a generator object which yields integers in the same order as inorder traversal. A multi-dimensional array is a recursive data st

leetcode.com

https://ko.javascript.info/generators

 

제너레이터

 

ko.javascript.info

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Generator

 

Generator - JavaScript | MDN

Generator 객체는 generator function 으로부터 반환되며, 반복 가능한 프로토콜과 반복자 프로토콜을 모두 준수합니다.

developer.mozilla.org

 

Comments