2020. 4. 10. 12:53ㆍ웹/Javascript(ES6+)
iterator
-
반복 처리가 가능한 객체
-
시퀀스를 정의하고 종료시의 반환값을 잠재적으로 정의하는 객체
-
반복자는 두 개의 속성(value, done)을 반환하는 next() 메소드 사용하여 객체의 iterator protocol 을 구현
-
반환되는 value 속성은 현재 iterator 가 가리키는 곳의 값을 가리키며, done 속성은 iterator 가 끝까지 도달했는지를 구분해주는 true/flase 값을 가짐
-
Array, String, Map, Set, DOM이 iterable, 이러한 요소를 탐색할 수 있게 하는 객체가 iterator
예제)
const furitArr = ['사과', '배', '오렌지'];
const iterator = furitArr[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
-- 출력 결과 --
{value: "사과", done: false]
{value: "배", done: false]
{value: "오렌지", done: false]
{value: undefined, done: true]
예제) Arry.prototype[Symbol.iterator]()
예제) String.prototype[Symbol.iterator]()
※ iterator protocol
for-of 문
-
반복가능한 객체 (Array, Map, Set, String, TypedArray, arguments 객체 등을 포함)에 대해서 반복
-
각 개별 속성값에 대해 실행되는 문이 있는 사용자 정의 반복 후크를 호출하는 루프를 생성
예제)
const fruitArr= ['사과', '배', '오렌지'];
for(const element of fruitArr){
console.log(element);
}
-- 출력 결과 --
사과
배
오렌지
iterator 와 for-of 활용
예제) 피보나치 수열
const fibo = {
maxStep: 20,
[Symbol.iterator]() {
let previos =0,
current = 1,
step = 0,
maxStep = this.maxStep;
return {
next() {
[previous, current] = [current, previous + current];
return {
done: step++ >= maxStep,
value: current
};
}
};
}
};
for(const el of fibo) {
console.log(el);
}
-- 출력 결과 --
1
2
3
5
...
6765
10946
-
Symbol.iterator 속성으로 하는 함수를 정의, next() 함수를 속성으로 가지는 객체를 반환
-
next() 함수는 으로 done, value 속성을 가짐
-
for-of 문을 통해 done 이 true 가 될때 까지 루프
예제) funtion*과 yield 키워드 사용
const fibo = {
maxStep: 20,
*[Symbol.iterator]() {
let previous =0,
current = 1,
step = 0,
maxStep = this.maxStep;
while(step++ < maxStep) {
[previous, current] = [current, previous + current];
yield current;
}
}
};
for(const el of fibo) {
console.log(el);
}
-- 출력 결과 --
1
2
3
5
...
6765
10946
-
generator 함수는 전체 함수가 종료되면 iterator도 종료, yield current 를 통해 값이 전달됨
-
yield current 가 호출되면 generator 함수가 잠시 멈추었다가 다음 for-of 루프를 돌때 이어서 실행
※ generator 함수
-
iterator 규격을 간단하게 처리하기 위한 generator 기능이 표준으로 정의되어 있음
-
function* 은 generator 함수이며 iterator를 반환하는 함수
-
yield 는 return과 유사, return은 함수를 끝내지만 yield 는 함수를 잠시 멈추었다가 다음에 호출되었을 때 다시 그 이후 부터 시작
예제) iterator 객체 생성
const fibo = function* (maxStep) {
let previous =0,
current = 1,
step = 0;
while(step++ < maxStep) {
[previous, current] = [current, previous + current];
yield current;
}
};
for(const el of fibo(20)) {
console.log(el);
}
-- 출력 결과 --
1
2
3
5
...
6765
10946
-
generator 함수를 변수에 선언하여 사용하더라도 직접 iterator 처럼 사용 가능
예제) iterator 객체를 통한 비동기 요청 흐름제어 활용
function getDOM() {
const xhr = new XMLHttpRequest();
xhr.open("/fetchDOM");
xhr.onload = function() {
xhrRequests.next(xhr.responseText);
}
xhr.send();
}
function getData() {
const xhr = new XHMLHttpReqeust();
xhr.open("/fetchData");
xhr.onload = function() {
xhrRequests.next(xhr.responseText);
}
xhr.send();
}
function manipulateDOM(dom, data) {
// Fix DOM
}
const xhrRequests = function* () {
let dom, data;
dom = yield getDOM();
data = yield getData();
yield manipulateDOM(dom, data);
}
-
getDOM, getData, manipulateDOM 을 순서대로 호출하고자 할때 흐름 제어
-
xhrRequests 변수는 iterator 객체로 전체 흐름을 제어, 각 함수가 실제 처리하는 역할 담당
-
xhrRequests 함수 내에서 각 순서 보장이 필요한 XHMLHttpRequest 들을 호출하고, 각 함수에서는 비동기 요청이 완료되면 onload 이벤트 핸들러를 통해 다음단계 next() 함수 호출
출처
속깊은 JavaScript(양성익)
'웹 > Javascript(ES6+)' 카테고리의 다른 글
비동기 처리 - async & aswait (0) | 2020.06.17 |
---|---|
비동기 처리 - Promise (0) | 2020.06.16 |
Rest, Spread 연산자 (0) | 2020.04.09 |
Destructuring(구조 분해 할당) (0) | 2020.04.08 |
템플릿 리터럴 문자열 표현식 (0) | 2020.04.08 |