안녕하세요 ! 오늘은 javascript의 generator (제너레이터) 함수에 대해 알아보겠습니다.
generator 함수는 일반적인 함수와 모양도 기능도 조금 다른데요, 함수의 실행을 중간에 멈췄다가 재개할 수 있는 기능이 있답니다! 이 말인즉, 다른 작업을 하다가 다시 돌아와도 진행이 멈췄던 부분부터 이어서 실행할 수 있는 함수라는 뜻입니다. 듣기만 해도 유용할 것 같지 않나요 ?!
쉬운 코드를 함께 보면서 generator 함수와 친해져 봅시다 ! 🌳🌲📗

우선, generator 함수를 선언할 때에는 function 키워드 바로 뒤에 '*'만 붙여주시면 됩니다. 다른 새로운 키워드 2개가 보일 텐데요, 자세한 설명을 하기에 앞서 결론적인 이야기부터 나누자면 "yield"라는 키워드를 만났을 때 함수의 실행이 정지되며, generator함수에서 next()함수를 호출하면 다시 새로운 yield 키워드를 만날 때까지의 코드들이 실행되는 기능이 있습니다. 다음 yield 키워드를 만나면 또다시 정지되고요.
위 코드를 더 디테일하게 설명하자면,
함수 외부에서 처음으로 next를 호출했을 때 generator 함수 속에서는 yield 1;이 나오기 전까지의 코드만 실행됩니다. 그럼 1은 출력될테고, 다음 줄의 yield 1을 만나면 함수의 실행이 정지되겠죠. 이 때 함수 외부에서 두 번째로 호출되는 next 함수에 의해 또다시 다음 yield가 나올 때까지 함수가 진행됩니다. 그렇게 함수는 2를 출력한 후 yield 2 코드를 만나게 되고, yield를 만났으니 또 그 즉시 함수의 실행은 멈추게 되는 겁니다.
결론적으로는 1과 2가 출력되겠네요.
자, 지금까지 대충 generator 함수의 모양과 형태를 훑어봤는데, 이 generator 함수는 우리가 평소에 쓰던 일반 함수와 어떤 차이들이 있는 걸까요? 차이점을 알아보기에 앞서, 필수적으로 아셔야 하는 개념인 iterable(이터러블)과 iterator(이터레이터)에 대해 잠시 짚고 넘어가는 시간을 갖도록 하겠습니다. 이건 사실 따로 빼서 포스팅을 해도 무방할 정도로 중요한 개념들이랍니다 ! ( 결국 따로 뺐습니다.. 아래의 포스팅을 꼭 참고해 주세요 !! ) 🚨
🚨🚨🚨🚨
https://with-mimi.tistory.com/entry/javascript-iterable%EA%B3%BC-iterator
[javascript] iterable과 iterator
🚨🚨🚨🚨 (= 반복 / 순회 가능한 객체 ) ☝🏻 iterable (이터러블) : for ...of 등의 문법을 이용하여 각 요소를 반복할 수 있는 객체. 이터러블 프로토콜을 준수한 객체. 이터러블 프로토콜을 준수
with-mimi.tistory.com
자, 이제 iterable과 iterator가 무엇인지도 알았으니, 지금부터 본격적으로 generator 함수는 우리가 평소에 쓰던 일반 함수와 어떤 차이가 있는지 알아봅시다 !
1. 함수 실행의 제어권을 함수 호출자에게 양도(yield)할 수 있다. ☝🏻
함수 호출자가 next 메소드를 언제 얼마나 호출하느냐에 따라 함수 실행의 결과가 그때그때 달라지겠죠. 기존 함수의 경우 우리에게는 함수를 호출하고 매개변수를 전달하는 것이 최선이었는데 말입니다. generator 함수의 경우 함수 호출자가 어느정도 함수 실행 통제권을 얻게 되는 겁니다.
2. generator 함수는 generator 객체를 반환한다. ✌🏻
기존의 일반적인 함수의 경우 호출이 되었을 때 위에서부터 순차적으로 코드를 실행하게 됩니다. 그러나 generator 함수는 실행 시 코드를 실행하는 것이 아니라, generator 객체를 만들어 반환합니다. 앞서 배운 iterator의 개념을 적용시키면 됩니다. generator 함수는 iterable하므로 객체의 요소를 순회할 수 있으며, next()메소드를 통해 value와 done을 속성으로 가진 generator 객체가 반환될 것입니다. 여기서 속성 value는 yield가 있을 때는 yield의 오른쪽 값을 가지며 yield가 없을 때는 최종 return값을 가집니다. done은 함수가 끝이 났을 때는 true, 아직 진행중일 때는 false 값을 가지는 변수입니다.
추가로 iterator 중 generator 함수만 유일하게 next()에 인수를 넣어 전달할 수도 있답니다 ! 🫢

우선 맨 아래의 코드를 보면 generator 함수에 next 메소드를 3번 호출한 것을 볼 수가 있습니다. 처음으로 next 를 호출했을 때는, 처음으로 만난 yield에 막힐 것입니다. 이 때 반환되는 generator 객체의 value로는 yield 의 오른쪽 값인 "첫 번째 숫자를 입력해주세요." 가 되며, done으로는 false가 자리하게 되겠죠. done 변수는 함수가 끝나기 전까지는 계속 false값을 가질 테니까요. 다음 next 호출을 하는데 이때 인수로 전달된 3은 num1에 할당되어 출력된답니다! 😮또한 이번에도 value는 yield 바로 옆의 문장이 되겠고요, 마지막 세 번째 next 호출에 의해서는 우선 num2에 할당된 5가 출력되겠고, 이번 next함수에 의해 반환되는 객체의 경우 ,value는 최종 return값인 8, done은 이제 아래에 더는 yield가 없으므로 ( 즉 함수가 모두 끝이 났으므로 ) true값을 가지게 되겠죠.
**** 주석을 보시면 next 3번의 호출에 의해 3번 반환된 generator 객체의 모습을 보실 수 있습니다 !
3. generator 함수는 값을 미리 만들어두지 않는다. 그때그때 필요한 값만 생성한다. 다르게 말하면, 필요한 순간까지 계산을 미룰 수가 있다. ( 그렇다면 메모리 절약 부분에서도 이득이겠죠?! ) 따라서 일반적인 함수와 다르게, while(true)문을 돌려도 무한루프에 빠지지 않는다.

이 코드를 콘솔창에 찍어보면 아시겠지만, next를 호출할 때마다 index가 하나 올라간 숫자가 출력될 뿐입니다. 다음 next 호출이 들어올 때까지 while문은 멈춰 있을 수 밖에 없는게, 반복 한 번이 수행될 때마다 yield키워드가 떡 하니 있기 때문입니다. 다음 next호출이 들어와야 또 다음 yield를 만날 때까지 함수가 실행될 수 있으니까요 ! 💡
마지막으로 하나만 더 소개드리고 마치도록 하겠습니다.
generator 함수 안에서 "yield*"을 통해 다른 generater 함수를 부를 수도 있습니다. 또한, generator 함수를 for...of 구문을 사용하여 순회할 수 있듯, 전개구문(...)을 사용하여 generator 함수의 요소들을 펼쳐낼 수도 있답니다. 이 세 가지 문법은 비단 generator 함수 뿐만 아니라 iterable 프로토콜을 따르는 모든 객체에 적용이 가능합니다 !

오늘은 generator(제너레이터) 함수를 함께 알아보았습니다. 드디어 자바스크립트 한바퀴를 다 돌렸네요 휴 🥹 아직 올려야 할 포스팅은 많이 남았지만 말입니다..
그래도 이제 리액트라는 것을 공부해볼 수 있겠어요 🌟🙏🏻
오늘도 읽어주셔서 감사합니다 ! 🩷🩵🩶
+ 완강 인증샷 .. 📸

'javascript' 카테고리의 다른 글
[javascript] Symbol(심볼)형 (5) | 2024.03.18 |
---|---|
[javascript] iterable과 iterator 정리 (19) | 2024.03.18 |
[javascript] async, await (7) | 2024.03.15 |
[javascript] 유용한 객체 메소드 / 숫자 메소드 총정리 (5) | 2024.03.13 |
[javascript] 클로저(closure) (3) | 2024.03.11 |