JavaScript - Iterable
in JS on 공부, Javascript
Iterable, iterator, generator를 볼 것이다.
iterable
내부 요소들을 공개적으로 탐색(반복)할 수 있는 데이터 구조이다.
배열 ,set, map, string.
모두 Symbo.iterator라는 메소드를 가지고 있다.
const obj = {0:1, 1:2, 2:3, length:3} //유사배열 객체. not iterable
generator를 호출한 결과
function* generator(){
yield 1
yield 2
yield 3
}
const gene = generator()
gene.next() // 1
gene.next() //2
gene.next() //3
gene.next() //undefined
Array.from(str)//안에 iterable한 객체를 넣으면 배열로 반환해줌. 이건 split과 같음
Array.from(gene) // [1,2,3]
spread operator 이용
[...arr]
console.log(..str)
console.log(...set)
해체 할당 가능
const [arrA,,arrC] = arr
위의 애들이 다 되는 이유는 symbol.iterator와 관련 있음
const iter = arr[Symbol.iterator](); //배열의 prototype에 정의되어 있다.
iter // Array Iterator{}
iter.next() //1
iter.next() //2
iter.next() //3
iter.next() //done:false, undefined
Array.from(iterable)
...iterable
[,,a] = iterable //해체할당
//동작 원리가 다 똑같다.
var a = iterable[Symbol.iterator]() //얘가 곧 iterator
a.next() => 반복호출. done이 true가 되기 전까지.
for(let x of iterable){
} //얘도 iterator 실행시킴.
const a = [
new Promise((resolve, reject)=> {setTimeout(resolve, 500, 1)}), //시간 제한. 0.5초 뒤에 1이란 값을 넘겨줄 거다.
new Promise((resolve, reject)=> {setTimeout(resolve, 100, 2)}),
3456,
'abc'
]
Promise.all(a) //iterable이 올 수 있음. promise이든 아니든간에 실행을 다 해버림.
.then(v=> {console.log(v)})
.catch(err=> {console.error(err)})
Promise //[1,2,3456,'abc',3]
generator - yield* 문법으로 이용 가능
const makGenerator = iterable => function*(){
yield* iterable //=yield 1; yield 2; yield 3;
}
const aGen = makeGenerator(arr)();
aGen.next() //1
aGen.next() //2
여기까지는 모두 내부적으로 Symbol.iterator / generator를 실행하여 iterator로 변환한 상태에서 next()를 반복 호출하는 동일한 로직을 기반으로 한다.
iterable 객체에 symbol.iterator가 정의되어 있지 않은 경우
```const obj = { a: 1, b: 2, Symbol.iterator{ return 1 //안됨. 근데 반환할 수 있는 방법ㅂ이 있음 } }
iterable한 개체를 인자로 받을 수 있느 개체
new Map()
new Set()
//아래 두개 자체는 iterable 하지 않음
new WeakMap()
new WeakSet()
Promise.all()
Promise.race()
Array.from()