Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

백고등어 개발 블로그

자바스크립트 이터러블, 이터레이터, 제너레이터 본문

javascript

자바스크립트 이터러블, 이터레이터, 제너레이터

백고등어 2022. 10. 12. 01:20
728x90
아래 글은 주홍철 저자의 "실시간 모니터링 시스템을 만들며 정복하는 MEVN" 책 내용의 일부분을 인용하여 작성하였습니다.

이터러블(Iterable)

이터러블은 일반적으로 어떤 요소들을 순회하며 쉽게 탐색할 수 있는 자료구조를 말합니다.
자바스크립트에서는 이터러블 프로토콜이라는 규칙을 준수한 객체를 말합니다.(즉, 해당 규칙을 준수하지않은 객체는 이터러블하다고 할 수 없습니다.)
그 규칙이란 어떤 객체가 Symbol.iterator 메서드를 가짐을 뜻합니다.
그 메서드는 next()라는 메서드를 가지고 있는 객체를 반환하고 해당 객체는 valuedone 프로퍼티를 가지고 있습니다.
대표적으로 배열은 Symbol.iterator 메서드를 가지고 있습니다.
*다른말로 배열은 빌트인 이터러블(built-in iterable)이라고도 합니다.

빌트인 이터러블(built-in iterable)

아래의 표준 빌트인 객체들은 빌트인 이터러블입니다.

Array Array.prototype[Symbol.iterator]
String String.prototype[Symbol.iterator]
Map Map.prototype[Symbol.iterator]
Set Set.prototype[Symbol.iterator]
TypeArray TypeArray.prototype[Symbol.iterator]
arguments arguments.prototype[Symbol.iterator]
DOM 컬렉션 NodeList.prototype[Symbol.iterator]HTMLCollection.prototype[Symbol.iterator]

이터레이터(Iterator)

이터러블한 것들은 모두 이터레이터를 반환할 수 있습니다.
이터레이터라는 것은 이터러블의 요소를 순회할 때 쓰는 포인터로 이터러블에서 값을 뽑아낼 때 사용됩니다.
이터레이터의 next() 메서드를 통해 이터러블을 순회하며 value와 done 속성을 사진 이터레이터 객체를 반환할 수 있습니다.
즉, 이터레이터는 이터러블에 Symbol.iterator 메소드를 호출했을 때 반환되는 값을 의미합니다.
이터러블한 객체를 for…of 형태로 순회했을 때의 작동원리는 이터레이터의 next() 메서드를 작동시켜 가며 탐색하는 것과 동일합니다.

제너레이터(Generator)

선언 시, 함수 이름 왼쪽에 “*”를 붙입니다.
이터레이터를 쉽게 만들 수 있으며 spread 연산자, for of 등을 통해 yield 의 value 만을 끄집어내어 쉽게 이터러블한 객체를 반환할 수 있는 함수입니다.

1. 제너레이터를 이용한 코루틴

아래는 예시 코드입니다.

const log = console.log;

function *map(f, list) {
	for(const a of list) {
		yield f(a);
	}
}

const add = a => a + 10;
const a = [1, 2, 3];
const customGenerator = map(add, a);

log(customGenerator.next());
log("어떤 로직 1");
log(customGenerator.next());
log("어떤 로직 2");
log(customGenerator.next());

/*
{ value: 11, done: false }
어떤 로직 1
{ value: 12, done: false }
어떤 로직 2
{ value: 13, done: false }
*/

이 제너레이터를 사용하면 코루틴이라는 것을 할 수 있습니다.
보통 알고 있는 map이라는 함수는 그저 배열을 어떤 함수를 통해 한번에 새로운 배열로 반환하는 함수입니다.
하지만 제너레이터 함수를 통해 반환된 이터레이터 객체의 next() 메서드를 이용하면 자신이 원하는 시점에 순차적으로 요소를 순회할 수 있습니다.
next() 메서드를 콘솔에 찍어보면 value와 done이 찍힙니다.
value는 yield한 값, done은 return 유무를 판단합니다.
다시 말하면, next() 메서드를 사용하기 전에는 yield value 꼴의 value가 반환되지 않습니다.
next() 메서드가 호출되면 value와 done 속성을 가진 값이 반환됩니다.
그 후 다시 for of 문 안에서 호출 당시의 위치를 기억하고 다시 yield가 발동하면 그 위치를 기억해서 그 위치부터 함수 내부의 제어권이 넘어가며 로직이 이어지게 됩니다.
함수의 작동 시점을 자유자재로 구현하는 것을 전문적인 용어로 “코루틴”이라고 합니다.

  • 제너레이터의 코루틴 작동원리
    • yield 문이 있는 해당 값을 제너레이터 객체가 그 부분에 해당하는 스택프레임(매개변수, 로컬 변수, 실행위치)를 복사해 저장해둡니다.
    • 동시에 자바스크립트 콜스택에서는 해당 스택프레임을 제거합니다.
    • next() 메서드가 발동되면 스택프레임을 복원해 실행합니다.

2. 제너레이터를 이용한 지연평가

제너레이터를 사용하여 할 수 있는 작업중 대표적으로 “지연평가”라는 것이 있습니다.
지연평가를 하면 파이프라인에서 제너레이터로 연결된 함수들이 합쳐지는 듯한 효과를 내서 성능 향상에 도움이 됩니다.
간단 요약

  • 갖춰진 순회 가능한 배열을 전체적으로 순회할 필요없이 빠르게 필요한 부분만 순회 가능! (지연평가의 장점)

제너레이터 지연평가에 대한 내용은 아래의 블로그들을 참고해주시길 바랍니다.

[Javascript] Generator 활용과 장점 (iterable, iterator, lazy evaluation)

들어가며 generator, iterator, iterable의 상세한 설명은 없습니다. 궁금하신 분들은 아래의 포스팅을 먼저 읽고 보는 것을 추천드립니다. bbaktaeho-95.tistory.com/79 [Javascript] Generator, Iterator, Itera..

bbaktaeho-95.tistory.com

[Javascript] 지연 평가(Lazy evaluation) 를 이용한 성능 개선

컴퓨터 프로그래밍에서 느긋한 계산법(Lazy evaluation)은 계산의 결과 값이 필요할 때까지 계산을 늦추는 기법이다. 위키피디아에서 지연 평가를 설명하는 문장이다. 지연 평가는 필요 할 때까지

armadillo-dev.github.io

제너레이터 참고

시리즈 | Generator 함수를 이해하자 - rohkorea86.log

20-Resources-on-ES6-for-JavaScript-Developers.jpg [해당 이미지는 다음 링크에서 사용했습니다 : http://welllin.net/javascript-es6-generator/] #제네레이터함수 #“어디에” 제네레이터 함수를 써야 하는가? #느긋한계

velog.io

참고

이터러블 / 이터레이터 / 제네레이터

자바스크립트 공부중 어려웠던 내용을 복습해 보려고 한다. 그 중 하나가 Iterble/Iterator/Generator 였다. 패스트캠퍼스 Nodejs 올인원 패키지에서는 제대로 설명해 주지 않아서 많이 아쉬웠다. 강좌의

velog.io

728x90