백고등어 개발 블로그
자바스크립트 이터러블, 이터레이터, 제너레이터 본문
아래 글은 주홍철 저자의 "실시간 모니터링 시스템을 만들며 정복하는 MEVN" 책 내용의 일부분을 인용하여 작성하였습니다.
이터러블(Iterable)
이터러블은 일반적으로 어떤 요소들을 순회하며 쉽게 탐색할 수 있는 자료구조를 말합니다.
자바스크립트에서는 이터러블 프로토콜이라는 규칙을 준수한 객체를 말합니다.(즉, 해당 규칙을 준수하지않은 객체는 이터러블하다고 할 수 없습니다.)
그 규칙이란 어떤 객체가 Symbol.iterator 메서드를 가짐을 뜻합니다.
그 메서드는 next()라는 메서드를 가지고 있는 객체를 반환하고 해당 객체는 value와 done 프로퍼티를 가지고 있습니다.
대표적으로 배열은 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' 카테고리의 다른 글
바닐라 Javascript import 테스트 시 발생한 에러 (2) | 2022.11.02 |
---|---|
객체지향 프로그래밍(OOP, Object-Oriented Programming) 개념과 프로토타입 상속 (0) | 2020.10.28 |
자바스크립트 splice 메소드 사용시 주의점 (0) | 2020.10.15 |
Javascript 이벤트와 이벤트 중단 (0) | 2020.09.23 |
DOM 노드의 생성, 수정, 삭제 (0) | 2020.09.23 |