(실행 결과: 1과 2를 넣었을 때)
첫 번째 수? → 1
두 번째 수? → 2
3
자바스크립트 개발자 여러분, Yield를 아십니까? 아마 많이 생소할 것이다. 제너레이터라니... yield를 몰라서 면접에서 혼쭐난 개발자분도 계셨다. 사실 잘 쓰지 않는 제너레이터를 왜 알아야할까...(쓰지 않는게 아니라 생소할 뿐이었다. 비교적 최신문법) 나 또한 deep dive javascript
를 공부하며, 그냥 훌러덩 넘어간 부분이었는데, 현재 사용하는 비동기와 그에 따른 기술의 전반적인 이해를 위해선 이터레이터와 더불어 반드시 필요한 내용이었다. 대-충 그냥저냥 비동기를 사용했다면 반드시 generator와 yield에 대해서 알아두자.
3rd) Generator yield & next() - ES2016 ~ ES2017
function *
function 에 *
이 찍힌 것을 본 적이 있는가? 이를 보게 된다면 이 것은 generator이다. 아마 본 적이 없을 것이다. 이는 함수의 실행을 제어하겠다는 의미인데, 함수를 부른 caller
에게 특정 상황에서 실행의 제어권을 넘긴다는 소리다.
caller는 함수를 부른 친구이다. 실행시
yield
를 만나면 제너레이터는 호출자(caller)에게 제어권을 넘겨야한다.
function* 제너레이터() {
yield hi
...
}
제너레이터(); <<< 얘가 caller(콜러콜러)
generator를 호출하면 iterator를 얻는다. 즉, next() 메서드를 호출 가능하다는 뜻이다.
(next() -> yield -> next() -> yield -> ... -> return)
제너레이터 함수는 화살표 함수와 생성자 함수로 표현할 수 없으며 반드시 function*
키워드를 사용한다.
function* 제너레이터() {
const a = yield "첫번째 수는?";
const b = yield "두번째 수는?";
console.log("a, b :>> ", a, b);
return a + b;
}
const it = 제너레이터();
console.log(it.next());
console.log(it.next(1));
console.log(it.next(2));
함수가 중간에 멈춘다는 것을 볼 수 있다. 신기하다. 지혼자 실행하고 결과만 반환하던 놈인데, 내가 yield라는 애의 도움을 통해서 함수를 통제 할 수 있었다. next()를 사용할 수 있는 것으로 봐서 이는 iterator를 반환한다고 볼 수 있다.
기존 작성한 Stack과 Queue의 iterator를 generator 함수로 작성하고, p.109의 지하철 노선도 iterator를 generator함수로 작성하시오.
(기능은 동일함)
iterator 만들기 // next() 함수를 직접 작성해서 리턴해줬었다.
[Symbol.iterator]() {
let idx = -1;
return {
next: () => {
idx += 1;
return { value: this._arr[idx], done: !this._arr[idx] };
},
};
}
generator 만들기 // next()를 사용할 수 있기 때문에 아래처럼 만들 수 있다.
*[Symbol.iterator]() {
for (const k of this._arr) {
yield k;
}
}
iterator 만들기 // next() 함수를 직접 작성해서 리턴해줬었다.
[Symbol.iterator]() {
let idx = LINE2.indexOf(this.start) - 1;
console.log("🚀 ~ file: shsubway.js ~ line 14 ~ Subway ~ idx", idx);
let done = false;
return {
next: () => {
idx = idx === LINE2.length - 1 ? 0 : idx + 1;
done = done || LINE2[idx - 1] === this.end;
return { value: done ? undefined : LINE2[idx], done };
},
};
}
generator 만들기 // next()를 사용할 수 있기 때문에 아래처럼 만들 수 있다.
*[Symbol.iterator]() {
let idx = LINE2.indexOf(this.start) - 1;
let done = false;
while (!done) {
idx = idx === LINE2.length - 1 ? 0 : idx + 1;
done = done || LINE2[idx - 1] === this.end;
yield LINE2[idx];
}
}
중간에 멈추는 건 어디서 본 적이 있지않은가. 모르고 사용했던 acync/await와 비슷한 모습이 보인다. 비동기처리를 위해 기다리는 모습이 yield와 닮아있다. 비동기가 어떻게 멈추는지 generator를 보며 이해할 수 있었다.
SSAC 영등포 교육기관에서 풀스택 실무 프로젝트 과정을 수강하고 있다. JS전반을 깊이 있게 배우고 실무에 사용되는 프로젝트를 다룬다. 앞으로 그 과정 중의 내용을 블로그에 다루고자 한다.