[ js ] iterator, generator

IKNOW·2024년 4월 27일

이터레이션 프로토콜

이터레이터는 그 자체로 쓸모있기보다, 더 쓸몽 있는 동작이 가능해 진다는 의미가 있다.

이터레이터 프로토콜은 모든 객체를 이터러블 객체로 변환할 수 있다.

class Log {
	constructor() {
		this.message = []
	}
	add(message) {
		this.message.push({message, timestamp: Date.now()})
	}
	[Symbol.iterator]() {
		return this.messages.values()
	}
}

const logList = new Log()
...

for (let log of logList) {
	console.log(`${log.message} @ ${ log.timestamp}`)
}

이터레이터를 직접 만드는 방법

class Log {
	//...
	[Symbol.iterator]() {
		let i = 0
		const messages = this.messages
		return {
			next() {
				if(i >= messages.length)
					return {value: undefined, done: true}
				return { value: messages[i++], done: false}
			}
		}
	}
}

제네레이터

이터레이터를 사용해 자신의 실행을 제어하는 함수를 제네레이터라고 한다. 제네레이터에는 새로운이 개념이 포함된다. 함수의 실행을 개별적 단계로 나눔으로써 함수의 실행을 제어할 수 있고, 실행중인 함수와 통신 할 수 있다.

제네레이터는 두 가지 예외를 제외하고는 일반적인 함수와 같다.

  1. 제네레이터는 호출자에게 제어권을 넘길수 있다.
  2. 네네레이터는 호출한 즉시 실행되지 않지만, 이터레이터를 반환하고, 이터레이터의 next 메서드를 호출함에 따라 실행된다.

제네레이터는 다음과 같이 작성할 수 있다.

function* rainbow() {
	yield 'red';
	yield 'orange';
	yield 'yellow';
	yield 'green'
	yield 'blue'
	yield 'indigo'
	yield 'violet'
}

yield 표현식과 양방향 통신

통신은 yield 표현식을 통해 이뤄진다.

function* interrogate() {
	const name = yield "What is your name?"
	const color = yield "What is your favorite color?"
	return `${name}'s favorite color is ${color}`
}

generator에서 중요한 점은 중요한 값을 return으로 반환하면 안된다. generator가 값을 반환하는 용도로는 yield를 사용해야 하고 return은 generartor를 종료하는 목적으로 사용해야 한다.

profile
조금씩,하지만,자주

0개의 댓글