Notice
Recent Posts
Recent Comments
Link
On a couch
[TIL] Generator 함수 (미완) 본문
callback 함수 부분을 읽다가 promise를 설명하면서 generator 함수를 사용하는 것을 보았다.
써 본 적이 없어 낯설었는데, 스터디원 한 분이 좋은 자료를 찾아주셨다!
https://dev.to/lydiahallie/javascript-visualized-generators-and-iterators-e36
개념
- generator 함수는 ES6에서 소개되었다.
- 일반 함수가 run-to-completion 모델(작업이 완료될 때까지 멈추지 않음)을 따르는 반면, generator 함수는 원하는 곳에서 일시정지 시킬 수 있다.
기본 사용법
- function 키워드 뒤에 * 를 붙여서 생성한다
- generator 함수를 실행하면 generator object를 반환한다. 이것은 iterator이다.
- 함수 안에서 yield 키워드를 사용해 실행을 일시중지한다.
yield 키워드의 동작
function* genFunc() {
yield 'here'
console.log('First log')
yield 'there'
console.log('Second log')
return 'Done!'
}
- 함수를 처음 실행하면, 첫 번째 줄에서 'here'값을 수확(yield)한다
- 두 번째로 실행하면, 이전 yield 키워드 줄에서 시작한다. 그 후 두 번째 yield를 만날 때까지 쭉 실행한 다음 'there'값을 수확한다.
- 세 번째로 실행하면, 이전 yield 키워드 줄에서 시작한다. return 키워드를 만날 때까지 실행한 후 'Done!'이라는 값을 반환한다.
yield object의 동작
- 이전번에 어디서 yield했는지에 대한 상태를 기억하려면, 함수를 실행시켜서 변수에 할당해야 한다.
const genObj = genFunc()
- yieldobject의 프로토타입 체인 상에 next()라는 메소드가 있다. 이걸 처음 실행시키면 yield를 만날 때까지 실행하고, 수확 시 {value : 'here', done: false}를 반환한다.
- 다시 실행시키면 yield를 만날 때까지 실행하고(console.log('First log')), {value : 'there', done: false}를 수확해 저장한다.
- 다시 실행시키면 return를 만날 때까지 실행하고(console.log('Second log')), {value : 'Done!', done: true}를 반환해 저장한다.
- 함수의 iterator는 한 번만 순회 가능하므로, 이미 종료된 상태에서 다시 next() 메소드를 실행하면 계속해서 {value: undefinec, done:true}를 반환한다.
iterator의 활용
- 함수가 반환하는 yield object는 [Symbol.iterator] 속성을 가졌으므로, 반복 가능한 타입(string, array, object)의 특성을 활용할 수 있다.
- spread 문법으로 yiled object의 value들을 배열에 담아낼 수 있다.
- for...of 문을 활용해 각 yield 값에 원하는 작업을 실행할 수도 있다.
- [Symbol.iterator] 속성을 가지고 있지 않은 것(순환 가능하지 않은 것)에 수동으로 속성을 부여해서 순환 가능하게 만들 수 있다. 속성값으로는 { value: '...', done: false/true } 형태의 객체를 반환하는 next를 가진 iterator를 할당하면 된다. generator 함수는 기본적으로 iterator를 반환하기 때문에, 간단하게는 generator 함수를 실행해 할당해도 된다.
// 유사배열객체가 아니므로 원래는 순환할 수 없는 객체
const anyObject = {name : 'sol-namoo', adult: true}
// [Symbol.iterator] 속성에 자신을 yield하는 yield object를 할당
anyObject[Symbol.iterator] = function* () {
yield this
}
iterator의 개념을 어렴풋이 들은 적이 있어서 처음에는 'yield object가 iterator의 특성을 가지고 있다는 뜻이구나' 라고 이해했다.
읽다 보니 yeild object의 형태가 iterator 그 자체였다.
(https://pks2974.medium.com/javascript%EC%99%80-iterator-cdee90b11c0f)
예시가 너무 간단해, 이걸 읽는 것만으로는 확실지 않아서 직접 코드를 찍어가면서 확인하려 했더니 생각보다 시간이 든다.
일단 기본적인 것은 이해한 것 같아, 여기까지만 정리해 포스팅한다!
'프론트엔드 공부 > Javascript 읽기' 카테고리의 다른 글
[코어자바스크립트] 02 실행컨텍스트 메모 (0) | 2022.08.03 |
---|---|
[코어자바스크립트] 01 데이터타입 메모 (0) | 2022.08.02 |
[Eloquent] 1부 <언어> 필기 (0) | 2022.03.06 |