FRONTEND/React

[Javascript] Generater 제너레이터 와 Iterable Obj 이터러블 객체

neeon 2022. 9. 26. 13:27
728x90

일반 함수는 하나의 값(혹은 return 값이 없을 수도 있음)만을 반환.

but.

제너레이터(generator)를 사용하게 되면, 여러 개의 값을 필요에 따라 하나씩 반환(yield)할 수 있게 된다.

generator과 iterable 객체를 함께 사용하면 손쉽게 data stream을 만들 수 있다고 함.

 

* 이터러블(iterable)
- 반복 가능한(iterable, 이터러블) 객체는 배열을 일반화한 객체. 이터러블이라는 개념을 사용하면 어떤 객체에든 for..of 반복문을 적용할 수 있다.
- 배열이 대표적인 이터러블임. 배열 외에도 다수의 내장 객체의 반복도 가능. 

[ 이터레이터 iterator : obj[Sysbol.iterator]의 결과. 이어지는 반복 과정을 처리한다. ]

** 이터러블 규약
for..of 반복 구문을 사용하여 객체(반복 가능한 객체)를 반복할 때 값이 열거되고 내부에는 @@iterator 메서드가 그구현되어 있어야 함.

Sysbol.iterator() == @@iterator 

자바 스크립트의 내장 객체인 Array, String, Map, Set, Arguments 등이 이 이터러블 규약을 따른다.

 

제너레이터를 만들려면 '제너레이터 함수'라고 불리는 특별한 문법 구조인 function* 이 필요한데.. 

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

형식으로 선언하고, 하나씩 값을 불러오기 위해서는

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();

let one = generator.next();

alert(JSON.stringify(one)); // {value: 1, done: false}

이런 식으로 JSON.stringify() 문법을 사용해보도록 하자.

정의할 때에는 yield / 값을 얻어올 때에는 next , return , throw

1. next : 메서드를 호출할 때 마다, "새로운 yield"의 값과 "앞으로 yield할 값이 더 남았는지의 여부"를 반환.

   {value: ,done: false/true} 의 형태로 값 반환

2. return : 인수로 전달한 값을 반환하고 제너레이터를 종료.

   {value: 인수, done:true} 를 반환

3. throw: 인수로 전달받은 에러를 발생시키고 제너레이터를 종료.

   - 여기서 그냥 사용하게 되면 애플리케이션이 멈춰버리기 때문에 try~catch 문으로 예외처리를 해주어야 한다.

function* fun(){
	console.log('제너레이터 fun 실행');
    try{
    	yield 1;
        yield 2;
        yield 3;
    } catch(e) {
    	console.error(e);
    }
}

const f= fun();
console.log(f.next());
console.log(f.throw('error message test');
console.log(f.next());

> {value: 1, done:false}

> error message test

> {value: undefined, done:true}

> {value: undefined, done: true}

 

======

제너레이터 기능을 활용하면, 이터러블을 쉽게 구현할 수 있는데 특히 무한루프에서 多 활용..

- 무한수열, 무한 스크롤 등.. 의 기능을 구현할 때

const fibonacci = (function* () {
	let[pre, cur] = [0,1];
    while(true) {
    	[pre, cur] = [cur, pre+cur];
        yield pre;
    }
})();

for (const num of fibonacci) {
	if (num>1000) break;
    console.log(num);
}

이런 패턴이 자주 사용되니 메모해두면 좋다고 한다. feat. 피보나치 수열..

 

 

 

[ 참고 ]

https://blog.naver.com/tombyun/222444048304

 

자바스크립트 제너레이터! 조금씩 끊어서 사용하는 특별한 함수

제너레이터를 제대로 이해하려면, 먼저 함수에 대해 정확히 알고 있어야 해. 함수는 여러 명령문을 중괄호{ ...

blog.naver.com

https://ko.javascript.info/generators

 

제너레이터

 

ko.javascript.info

 

728x90