JavaScript Visualized: πŸ’‘πŸŽ Generators and Iterators

Posted on September 03, 2020Β  - Β 8 min read

reference: https://dev.to/lydiahallie/javascript-visualized-generators-and-iterators-e36

ES6에 μ•„μ£Ό λ©‹μžˆλŠ” 게 μΆ”κ°€λμŠ΅λ‹ˆλ‹€. κ·Έ 이름은 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μž…λ‹ˆλ‹€. πŸŽ‰ μ œκ°€ μ‚¬λžŒλ“€μ—κ²Œ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ— λŒ€ν•΄ 물으면 보톡 λŒμ•„μ˜€λŠ” λŒ€λ‹΅μ€: β€œκ·Έκ±Έ ν•œ 번 λ³Έ 적은 μžˆμ§€λ§Œ μ’€ ν—·κ°ˆλ €μ„œ κ·Έλƒ₯ μ•ˆ 봄”, β€œμ œλ„ˆλ ˆμ΄ν„°μ— λŒ€ν•œ λΈ”λ‘œκ·Έ 글을 μˆ˜λ„ 없이 μ½μ—ˆλŠ”λ° 아직도 이해가 μ•ˆ 돼”, β€œκ·Έκ±Έ μ•Œμ§€λ§Œ λˆ„κ°€ κ·Έκ±Έ μ“ΈκΉŒβ€ πŸ€” λ˜λŠ” 이런 것듀이 μ•„λ§ˆ 였랜 μ‹œκ°„ λ™μ•ˆ μƒκ°ν•˜λ©° λ‚˜ μžμ‹ κ³Ό λ‚˜ λŒ€ν™”κ² μ£ . ν•˜μ§€λ§Œ 이건 μ•„μ£Ό 쒋은 κΈ°λŠ₯μž…λ‹ˆλ‹€.

그럼, μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜κ°€ λ­˜κΉŒμš”? λ¨Όμ € 일반적이고 전톡적인 ν•¨μˆ˜λ₯Ό 보도둝 ν•˜μ£ . πŸ‘΅πŸΌ

generators and iterators 1

λ„€ 뭐 별 κ±° μ—†μ£ ! 둜그λ₯Ό 4번 λ‚¨κΈ°λŠ” ν‰λ²”ν•œ ν•¨μˆ˜μž…λ‹ˆλ‹€. ν˜ΈμΆœμ„ ν•΄λ³ΌκΉŒμš”!

β€œκ·Όλ° 리디아, μ™œ 이 λ»”ν•œ ν•¨μˆ˜λ₯Ό 보게 ν•΄μ„œ λ‚΄ μΈμƒμ˜ 5μ΄ˆλž€ μ‹œκ°„μ„ ν—ˆλΉ„ν–ˆμ§€?” μ•„μ£Ό 쒋은 μ§ˆλ¬Έμž…λ‹ˆλ‹€. λ³΄ν†΅μ˜ ν•¨μˆ˜λŠ” run-to-completion λͺ¨λΈμ„ λ”°λ¦…λ‹ˆλ‹€: ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄, ν•¨μˆ˜λŠ” μ™„λ£Œκ°€ 될 λ•ŒκΉŒμ§€ μ‹€ν–‰λœλ‹€ (음, μ–΄λ”˜κ°€μ— μ—λŸ¬κ°€ μ—†λ‹€λ©΄μš”.) 우린 μž„μ˜λ‘œ 쀑간에 μš°λ¦¬κ°€ μ›ν•˜λŠ” μ‹œμ μ—μ„œ ν•¨μˆ˜λ₯Ό 멈좜 μˆ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€.

이제 μ•„μ£Ό 멋진 λΆ€λΆ„μž…λ‹ˆλ‹€: μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λŠ” run-to-completion λͺ¨λΈμ„ λ”°λ₯΄μ§€ μ•ŠμŠ΅λ‹ˆλ‹€! 🀯 이 말은 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό μ‹€ν–‰ 쀑간에 μž„μ˜λ‘œ 쀑지 μ‹œν‚¬ 수 μžˆλ‹€λŠ” λœ»μΌκΉŒμš”? 음, λΉ„μŠ·ν•©λ‹ˆλ‹€! 이제 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜κ°€ 뭔지, μ–΄λ–»κ²Œ μ‚¬μš©ν•˜λŠ”μ§€ 보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

우린 function ν‚€μ›Œλ“œ 뒀에 * 기호λ₯Ό μ‚¬μš©ν•˜μ—¬ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

generators and iterators 3

ν•˜μ§€λ§Œ 이것이 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜κΈ° μœ„ν•΄ ν•΄μ•Όν•˜λŠ” μ „λΆ€λŠ” μ•„λ‹™λ‹ˆλ‹€! μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λŠ” μ‹€μ œλ‘œ 일반적인 ν•¨μˆ˜μ™€ μ™„μ „νžˆ λ‹€λ₯Έ λ°©μ‹μœΌλ‘œ λ™μž‘ν•©λ‹ˆλ‹€:

  • μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ ν˜ΈμΆœμ€ μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό λ°˜ν™˜ν•˜λŠ”λ°, μ΄λŠ” μ΄ν„°λ ˆμ΄ν„°μž…λ‹ˆλ‹€.
  • μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜ λ‚΄μ—μ„œ yield ν‚€μ›Œλ“œλ₯Ό 톡해 싀행을 쀑지 μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

그런데 이것이 뭘 μ˜λ―Έν• κΉŒμš”!?

λ¨Όμ € 첫 번째둜 가보죠: *μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ ν˜ΈμΆœμ€ μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.* 일반적인 ν•¨μˆ˜λ₯Ό 호좜 ν•  λ•Œ, ν•¨μˆ˜μ˜ λ°”λ”” μ˜μ—­μ΄ μ‹€ν–‰λ˜κ³  λ§ˆμ§€λ§‰μœΌλ‘œ 값을 λ°˜ν™˜ν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  λ•ŒλŠ”, μ œλ„ˆλ ˆμ΄ν„° 객체가 λ°˜ν™˜λ©λ‹ˆλ‹€! 그럼 λ°˜ν™˜λœ 값을 둜그둜 남겼을 λ•Œ μ–΄λ–»κ²Œ μƒκ²ΌλŠ”μ§€ 보도둝 ν•˜μ£ .

이제, μ•„μ£Ό λ³΅μž‘ν•΄λ³΄μ΄λŠ” 것듀 λ•Œλ¬Έμ— 내적 λΉ„λͺ…을 (ν˜Ήμ€ ν˜„μ‹€λ‘œ πŸ™ƒ) 지λ₯΄μ‹€ κ±°μ˜ˆμš”. ν•˜μ§€λ§Œ κ±±μ • λ§ˆμ„Έμš”. μ—¬κΈ° 둜그둜 남겨진 속성듀을 μ‹€μ œλ‘œ μ‚¬μš©ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ μ œλ„ˆλ ˆμ΄ν„° κ°μ²΄λŠ” 뭐가 쒋은 κ±ΈκΉŒμš”?

λ¨Όμ € 잠깐 λ’€λ‘œ κ°€μ„œ 일반 ν•¨μˆ˜μ™€ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ 두 번째 차이에 λŒ€ν•΄ 닡을 ꡬ해야 ν•©λ‹ˆλ‹€: *yield ν‚€μ›Œλ“œλ₯Ό 톡해 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ 싀행을 μ€‘μ§€μ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€.*

μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ‘œ 우린 μ΄λ ‡κ²Œ μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€. (genFuncλŠ” generatorFunction의 μ€„μž„λ§μž…λ‹ˆλ‹€): μ €κΈ°μ—μ„œ yield ν‚€μ›Œλ“œκ°€ ν•˜λŠ” 일은 뭐죠? yield ν‚€μ›Œλ“œλ₯Ό λ§Œλ‚  λ•Œλ§ˆλ‹€ μ œλ„ˆλ ˆμ΄ν„°μ˜ 싀행이 μ •μ§€λ©λ‹ˆλ‹€. 그리고 κ°€μž₯ 쒋은 점은 λ‹€μŒμ— ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ©΄, 이전에 멈좘 곳을 κΈ°μ–΅ν•˜κ³  κ·Έ κ³³μ—μ„œλΆ€ν„° μ‹€ν–‰λœλ‹€λŠ” 점이죠! πŸ˜ƒκΈ°λ³Έμ μΈ λ™μž‘λ“€μž…λ‹ˆλ‹€. (λ‚˜μ€‘μ— μ• λ‹ˆλ©”μ΄μ…˜μœΌλ‘œ λ³΄μ—¬λ“œλ¦΄ν…Œλ‹ˆ κ±±μ •λ§ˆμ„Έμš”):

generators and iterators 5

  1. 맨 처음 μ‹€ν–‰λ˜λ©΄, 첫 번째 λΌμΈμ—μ„œ λ©ˆμΆ”κ³  λ¬Έμžμ—΄ κ°’ Β '✨' 을 μ€λ‹ˆλ‹€.
  2. 두 번째 μ‹€ν–‰μ—μ„œλŠ” 이전에 yield ν‚€μ›Œλ“œκ°€ μžˆλŠ” κ³³μ—μ„œ μ‹œμž‘μ„ ν•©λ‹ˆλ‹€. 두 번째 yield ν‚€μ›Œλ“œκ°€ λ‚˜μ˜€κΈ° μ „κΉŒμ§€ λ‚΄λ €κ°€λ©° 'πŸ’•' 값을 μ€λ‹ˆλ‹€.
  3. μ„Έ 번째 μ‹€ν–‰μ—μ„œλŠ” 이전 yield ν‚€μ›Œλ“œμ—μ„œλΆ€ν„° μ‹œμž‘ν•˜λ©°, return ν‚€μ›Œλ“œλ₯Ό λ§Œλ‚  λ•ŒκΉŒμ§€ μ‹€ν–‰λ˜κ³  'Done!'을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

그런데..μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ ν˜ΈμΆœμ—μ„œ λ°˜ν™˜ν•œ 것이 μ œλ„ˆλ ˆμ΄ν„° 객체인데 μ–΄λ–»κ²Œ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆμ„κΉŒμš”? πŸ€”μ—¬κΈ°μ—μ„œ μ œλ„ˆλ ˆμ΄ν„° 객체가 λ™μž‘ν•©λ‹ˆλ‹€!

μ œλ„ˆλ ˆμ΄ν„° κ°μ²΄λŠ” nextλΌλŠ” λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•©λ‹ˆλ‹€(ν”„λ‘œν† νƒ€μž… μ²΄μΈμ—μ„œμš”). 이 λ©”μ†Œλ“œλŠ” μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό λ°˜λ³΅ν•˜λŠ”λ° μ‚¬μš©λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ, yield둜 값을 λ„˜κ²¨μ€€ μƒνƒœλ₯Ό κΈ°μ–΅ν•˜κΈ° μœ„ν•΄ 우린 μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό λ³€μˆ˜μ— ν• λ‹Ήν•΄μ€˜μ•Ό ν•©λ‹ˆλ‹€. μ „ κ·Έκ±Έ genObj라고 λΆ€λ₯Όκ±΄λ° generatorObjectλ₯Ό μ€„μ˜€μ–΄μš”.

λ„€, μš°λ¦¬κ°€ 이전에 봀던 λ³΅μž‘ν•˜κ²Œ 생긴 λ…€μ„μž…λ‹ˆλ‹€. 그럼 genObjλΌλŠ” μ œλ„ˆλ ˆμ΄ν„° κ°μ²΄μ—μ„œ nextλ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œ 무슨 일이 μΌμ–΄λ‚˜λŠ”μ§€ 보도둝 ν•˜μ£ !

μ œλ„ˆλ ˆμ΄ν„°λŠ” 첫 번째 라인에 μžˆλŠ” 첫 번째 yield ν‚€μ›Œλ“œλ₯Ό λ§Œλ‚  λ•ŒκΉŒμ§€ μ‹€ν–‰λμŠ΅λ‹ˆλ‹€. 이것이 μ£ΌλŠ” κ°μ²΄λŠ” value 속성과 done 속성을 ν¬ν•¨ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

{ value: ... , done: ... }

value 속성은 μš°λ¦¬κ°€ λ„˜κ²¨μ€¬λ˜ κ°’μ΄λž‘ κ°™μŠ΅λ‹ˆλ‹€. done 속성은 Boolean κ°’μœΌλ‘œ, μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜κ°€ λ°˜ν™˜λ  λ•Œλ§Œ trueκ°€ λ©λ‹ˆλ‹€. (yieldκ°€ μ•„λ‹ˆμ˜ˆμš”! 😊).

μ œλ„ˆλ ˆμ΄ν„°μ—μ„œ λ°˜λ³΅ν•˜λŠ” κ±Έ λ©ˆμ·„λŠ”λ°, 마치 ν•¨μˆ˜κ°€ μ •μ§€ν•œ κ²ƒμ²˜λŸΌ 보이죠! 이게 정말 멋진 κ²λ‹ˆλ‹€. 그럼 next λ©”μ†Œλ“œλ₯Ό λ‹€μ‹œ ν˜ΈμΆœν•΄λ³΄μ£ ! πŸ˜ƒ

λ¨Όμ €, λ¬Έμžμ—΄ First log!κ°€ μ½˜μ†”μ— 둜그둜 λ‚¨κ²¨μ§‘λ‹ˆλ‹€. 이건 yieldλ‚˜ return ν‚€μ›Œλ“œκ°€ μ•„λ‹ˆλΌ 계속 μ§„ν–‰λ©λ‹ˆλ‹€! 그런 뒀에 'πŸ’•' 값이 μžˆλŠ” yield ν‚€μ›Œλ“œλ₯Ό λ§Œλ‚˜μ£ . λ„˜κ²¨μ§„ 객체엔 value μ†μ„±μ˜ κ°’μœΌλ‘œ 'πŸ’•' κ°€ 있고, done 속성이 μžˆμŠ΅λ‹ˆλ‹€. done 속성은 μ œλ„ˆλ ˆμ΄ν„°κ°€ 아직 λ°˜ν™˜λœ 것이 μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— false μž…λ‹ˆλ‹€.

거의 λ‹€ μ™”μ–΄μš”! nextλ₯Ό λ§ˆμ§€λ§‰μœΌλ‘œ ν˜ΈμΆœν•΄λ³΄μ£ .

λ¬Έμžμ—΄ Second log!κ°€ μ½˜μ†”μ— 둜그둜 λ‚¨κ²¨μ§‘λ‹ˆλ‹€. κ·Έ λ’€ return ν‚€μ›Œλ“œμ— κ°’μœΌλ‘œ Done!을 λ§Œλ‚©λ‹ˆλ‹€. λ°˜ν™˜λœ 객체의 value 속성엔 Done!이 μžˆμŠ΅λ‹ˆλ‹€. μ΄λ²ˆμ—” μ‹€μ œλ‘œ λ°˜ν™˜ν•œ 것이기 λ•Œλ¬Έμ— done μ—λŠ” trueκ°€ ν• λ‹Ήλ˜μ—ˆμŠ΅λ‹ˆλ‹€!

done 속성은 μ‹€μ œλ‘œ μ•„μ£Ό μ€‘μš”ν•©λ‹ˆλ‹€. 우린 μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό λ”± ν•œ 번만 μˆœνšŒν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ­λΌκ΅¬μš”?! 그럼 next λ©”μ†Œλ“œλ₯Ό ν•œ 번 더 ν˜ΈμΆœν•˜λ©΄ 무슨 일이 μΌμ–΄λ‚˜μ£ ?

κ·Έλƒ₯ 계속 undefinedκ°€ λ°˜ν™˜λ©λ‹ˆλ‹€. λ§Œμ•½ ν•œ 번 더 μˆœνšŒν•˜κ³  μ‹Άλ‹€λ©΄, μƒˆλ‘œμš΄ μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό μƒμ„±ν•˜μ‹œλ©΄ λ©λ‹ˆλ‹€!


방금 λ³΄μ…¨λ˜ κ²ƒμ²˜λŸΌ, μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λŠ” μ΄ν„°λ ˆμ΄ν„° (μ œλ„ˆλ ˆμ΄ν„° 객체)λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. 그런데, μ΄ν„°λ ˆμ΄ν„°λ₯Ό κΈ°λ‹€λ¦°λ‹€λŠ” 건? μš°λ¦¬κ°€ for of 루프λ₯Ό μ“Έ 수 μžˆλ‹€λŠ” κ±°κ³ , spread μ—°μ‚°μžλ₯Ό λ°˜ν™˜λœ κ°œκ²Œμ— μ“Έ 수 μžˆλ‹€λŠ” κ±ΈκΉŒμš”? κ·ΈλŸΌμš”! 🀩

ν•œ 번 [... ] 문법을 μ‚¬μš©ν•˜μ—¬ λ„˜κ²¨μ§„ 값듀을 spread μ—°μ‚°μžλ‘œ 넣어보죠.

λ˜λŠ” for of 루프λ₯Ό μ‚¬μš©ν•˜λŠ” 것도?!

μ—„μ²­λ‚˜κ²Œ κ°€λŠ₯μ„± 있죠!

그런데 무엇이 μ΄ν„°λ ˆμ΄ν„°λ₯Ό μ΄ν„°λ ˆμ΄ν„°λ‘œ λ§Œλ“œλ‚˜μš”? 우린 for-of 루프와 배열에 spread 문법, λ¬Έμžμ—΄, Map, Set λ˜ν•œ μ“Έ 수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€. 이것듀은 μ‹€μ œλ‘œ μ΄ν„°λ ˆμ΄ν„° ν”„λ‘œν† μ½œλ‘œ κ΅¬ν˜„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€: [Symbol.iterator]. λ‹€μŒκ³Ό 같은 값을 κ°–κ³  μžˆλ‹€κ³  해보죠. (μ•„μ£Ό μž₯ν™©ν•©λ‹ˆλ‹€ πŸ’πŸΌβ€β™€οΈ):

generators and iterators 13

array, string, generatorObjectλŠ” λͺ¨λ‘ μ΄ν„°λ ˆμ΄ν„°μž…λ‹ˆλ‹€! ν•œ 번 [Symbol.iterator] 속성 값을 보도둝 ν•˜μ£ .

그럼 λ°˜λ³΅ν•  수 μ—†λŠ” κ°’λ“€μ˜ [Symbol.iterator]값은 μ–΄λ–¨κΉŒμš”?

λ„€. κ·Έλƒ₯ μ—†μ£ . 그럼..μˆ˜λ™μœΌλ‘œ [Symbol.iterator] 속성을 μΆ”κ°€ν•˜κ³ , μˆœνšŒν•  수 μ—†λŠ” 것을 μˆœνšŒν•  수 μžˆλ„λ‘ λ§Œλ“€ 수 μžˆλ‚˜μš”? λ„€ κ°€λŠ₯ν•˜μ£ ! πŸ˜ƒ

[Symbol.iterator]λŠ” μ΄ν„°λ ˆμ΄ν„°λ₯Ό λ°˜ν™˜ν•΄μ•Ό ν•˜κ³ , 이전에 봀던 것 같은 객체에 next λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•΄μ•Όν•©λ‹ˆλ‹€: { value: '...', done: false/true }.

κ°„λ‹¨ν•˜κ²Œ μœ μ§€ν•˜κΈ° μœ„ν•΄ (μ œκ°€ μ’€ κ²Œμ„λŸ¬μ„œ) 우린 기본적으둜 μ΄ν„°λ ˆμ΄ν„°λ₯Ό λ°˜ν™˜ν•˜λŠ” κ²ƒμœΌλ‘œμ¨ [Symbol.iterator]의 값을 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ‘œ ν• λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€. 객체λ₯Ό μˆœνšŒν•  수 μžˆλ„λ‘ λ§Œλ“€μ–΄λ³΄κ³ , 전체 객체λ₯Ό λ„˜κ²¨μ€˜λ³΄λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€:

generators and iterators 16

우리 object 객체에 for-of λ£¨ν”„λ‚˜ spread 문법을 μ‚¬μš©ν•  λ•Œ μ–΄λ–»κ²Œ λ˜λŠ”μ§€ λ³΄μ‹œμ£ !

λ˜λŠ” 객체의 ν‚€λ§Œ μ–»κ³  μ‹Άλ‹€λ©΄μš”. β€œλ„ˆλ¬΄ 쉽죠. κ·Έλƒ₯ this λŒ€μ‹  Object.keys(this)만 λ„˜κΈ°λ©΄ λ©λ‹ˆλ‹€!”

generators and iterators 18

흠 ν•œ 번 해보죠.

였 이런. Object.keys(this)λŠ” λ°°μ—΄μ΄μ˜ˆμš”, 그럼 λ„˜κ²¨μ§€λŠ” 값은 배열이죠. κ·Έλ¦¬κ³ λ‚˜μ„œ 이 배열을 λ‹€λ₯Έ 배열에 spread 문법을 μ‚¬μš©ν•˜λ©΄ κ²°κ³ΌλŠ” 배열을 ν¬ν•¨ν•˜λŠ” 배열이 λ©λ‹ˆλ‹€. 이걸 μ›ν•˜λŠ” 건 μ•„λ‹ˆμ£ , 우린 각각의 ν‚€λ§Œ λ„˜κΈ°κ³  μ‹ΆμœΌλ‹ˆκΉŒμš”!

쒋은 μ†Œμ‹μ΄ μžˆμŠ΅λ‹ˆλ‹€! πŸ₯³yieldν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μ œλ„ˆλ ˆμ΄ν„° λ‚΄μ—μ„œ μ΄ν„°λ ˆμ΄ν„°λ₯Ό 각각 λ„˜κΈΈ 수 μžˆμ–΄μš”, κ·ΈλŸΌμ„ λΆ™μ—¬μ„œyieldλ₯Ό 해보죠! 첫 번째 yieldκ°€ 아보카도인 μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜κ°€ μžˆλ‹€κ³  해보죠. 그리고 λ‹€μŒ yieldμ—μ„œ λ‹€λ₯Έ 반볡자의 값듀을 각각 λ„˜κ²¨μ£Όκ³  μ‹Άλ‹€κ³  ν•©μ‹œλ‹€ (이번 κ²½μš°μ—” λ°°μ—΄μž…λ‹ˆλ‹€). 여기에yield`Β ν‚€μ›Œλ“œλ₯Ό μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€. 그러 λ‹€μŒ λ‹€λ₯Έ μ œλ„ˆλ ˆμ΄ν„°μ— *μœ„μž„ν•©λ‹ˆλ‹€!

genObj μ΄ν„°λ ˆμ΄ν„°μ—μ„œ μˆœνšŒλ˜μ–΄ 지기 전에, μœ„μž„λœ μ œλ„ˆλ ˆμ΄ν„°μ˜ 각각의 값듀이 λ„˜κ²¨μ§‘λ‹ˆλ‹€.

이것이 객체의 λͺ¨λ“  ν‚€λ₯Ό 각각 μ–»κΈ° μœ„ν•΄ μš°λ¦¬κ°€ ν•΄μ•Όν•˜λŠ” μΌλ“€μž…λ‹ˆλ‹€.


μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜μ˜ λ‹€λ₯Έ μ‚¬μš©λ²•μ€ μš°λ¦¬κ°€ (μΌμ’…μ˜) μ˜΅μ €λ²„ ν•¨μˆ˜λ‘œ μ“Έ 수 μžˆλ‹€λŠ” κ²λ‹ˆλ‹€. μ œλ„ˆλ ˆμ΄ν„°λŠ” 데이터가 λ“€μ–΄μ˜¬ λ•ŒκΉŒμ§€ κΈ°λ‹€λ Έλ‹€κ°€, 데이터가 전달 λ˜μ–΄μ•Ό 처리되게 λ©λ‹ˆλ‹€. μ˜ˆμ‹œμž…λ‹ˆλ‹€:

generators and iterators 22

이 λΆ€λΆ„μ˜ 큰 차이점은 이전 예제처럼 yield [value] ν˜•νƒœλ‘œ μž‘μ„±ν•˜μ§€ μ•Šμ•˜λ‹€λŠ” κ±°μ£ . κ·Έ λŒ€μ‹  secondλΌλŠ” λ³€μˆ˜μ— 값을 ν• λ‹Ήν•˜κ³  yield의 값은 λ¬Έμžμ—΄ First!κ°€ λ©λ‹ˆλ‹€. 이것은 next λ©”μ†Œλ“œκ°€ 처음 호좜되면 λ„˜κ²¨λ°›μ„ 값이겠죠.

next λ©”μ†Œλ“œλ₯Ό 처음 호좜 ν–ˆμ„ λ•Œ μ–΄λ–€ 일이 μΌμ–΄λ‚˜λŠ”μ§€ λ³΄μ‹œμ£ .

첫 번째 λΌμΈμ—μ„œ yieldλ₯Ό λ§Œλ‚˜κ³ , First! 값을 λ„˜κ²¨ λ°›μŠ΅λ‹ˆλ‹€. 그러면, λ³€μˆ˜ second의 값은 λ­˜κΉŒμš”?

μ‹€μ œλ‘œ κ·Έ 값은 μš°λ¦¬κ°€ λ‹€μŒ λ²ˆμ— ν˜ΈμΆœν•  next λ©”μ†Œλ“œμ— μ „λ‹¬ν•˜λŠ” κ°’μž…λ‹ˆλ‹€! 이번 νšŒμ°¨μ— λ¬Έμžμ—΄ 'I like JavaScript'λ₯Ό μ „λ‹¬ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ—¬κΈ°μ—μ„œ next λ©”μ†Œλ“œμ˜ 첫 번째 호좜이 아직 μž…λ ₯값을 κΈ°μ–΅ν•˜μ§€ μ•Šκ³  μžˆλ‹€λŠ” 뢀뢄이 μ€‘μš”ν•©λ‹ˆλ‹€. 첫 번째 회차의 ν˜ΈμΆœμ„ 톡해 κ°„λ‹¨ν•˜κ²Œ μ˜΅μ €λ²„λ₯Ό μ‹œμž‘ν•  수 있게 λ©λ‹ˆλ‹€. μ œλ„ˆλ ˆμ΄ν„°λŠ” 계속 μ§„ν–‰ν•˜κΈ° 전에 μž…λ ₯을 κΈ°λ‹€λ Έλ‹€κ°€, next λ©”μ†Œλ“œλ‘œ μ „λ‹¬λ˜λŠ” 값을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.


그럼 μ™œ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ €κ³  ν•˜λ‚˜μš”?

μ œλ„ˆλ ˆμ΄ν„°μ˜ κ°€μž₯ 큰 이점 쀑 ν•˜λ‚˜λŠ” 지연 평가(lazily evaluate)κ°€ λœλ‹€λŠ” μ μž…λ‹ˆλ‹€. 이 말은 next λ©”μ†Œλ“œμ˜ 호좜 이후 λ°˜ν™˜λ°›λŠ” 값이 μ‚¬μš©μžμ˜ νŠΉμ •ν•œ μš”μ²­ μ΄ν›„μ—λ§Œ 연산이 λœλ‹€λŠ” κ²λ‹ˆλ‹€! 일반적인 ν•¨μˆ˜λŠ” 이렇지 μ•Šμ£ : λ‚˜μ€‘μ— 값이 μ‚¬μš©λ˜μ–΄μ•Ό ν•  κ²½μš°μ— λŒ€λΉ„ν•˜μ—¬ λͺ¨λ“  값듀이 μƒμ„±λ©λ‹ˆλ‹€.

λͺ‡ 가지 λ‹€λ₯Έ μ‚¬μš© μ˜ˆμ‹œλ“€μ΄ μžˆμ§€λ§Œ, μ €λŠ” 보톡 μ•„μ£Ό 큰 데이터셋을 μˆœνšŒν•  λ•Œ 더 λ§Žμ€ μ œμ–΄ 방법을 μ–»κΈ° μœ„ν•΄ 이걸 μ‚¬μš©ν•©λ‹ˆλ‹€!

뢁클럽의 λͺ©λ‘μ΄ μžˆλ‹€κ³  가정해보죠! πŸ“š 예제λ₯Ό κ°„λ‹¨ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ ν•˜λ‚˜μ˜ κ±°λŒ€ν•œ μ½”λ“œ λΈ”λŸ­μ΄ μ•„λ‹ˆλΌ 각 λΆν΄λŸ½μ€ ν•˜λ‚˜μ˜ λ©€λ²„λ§Œ κ°–λŠ”λ‹€κ³  ν•˜κ² μŠ΅λ‹ˆλ‹€. λ©€λ²„λŠ” ν˜„μž¬ λͺ‡ κ°€μ§€μ˜ 책을 읽고 있고 κ·Έ 책듀은 books λ°°μ—΄μ—μ„œ ν‘œν˜„λ©λ‹ˆλ‹€!

generators and iterators 26

이제 idκ°€ ev812인 책을 μ°ΎμŠ΅λ‹ˆλ‹€. κ·Έκ±Έ μ°ΎκΈ° μœ„ν•΄ μš°λ¦¬λŠ” λ¨Έλ¦¬μ†μœΌλ‘œ μ€‘μ²©λœ for-loopλ‚˜ forEach 같은 헬퍼λ₯Ό λ– μ˜¬λ¦¬κ² μ§€λ§Œ, κ·Έ 말은 μš°λ¦¬κ°€ μ°ΎλŠ” νŒ€μ˜ 멀버λ₯Ό 찾은 뒀에도 데이터λ₯Ό 계속 λ°˜λ³΅ν•œλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€!

μ œλ„ˆλ ˆμ΄ν„°μ˜ λ†€λΌμš΄ 점은 μš°λ¦¬κ°€ μ§€μ‹œν•˜μ§€ μ•ŠλŠ” ν•œ 계속 μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점이죠. 이 말은 μš°λ¦¬κ°€ λ°˜ν™˜λœ μš”μ†Œλ₯Ό 평가할 수 있고 λ§Œμ•½ 그것이 μš°λ¦¬κ°€ μ°ΎλŠ” μš”μ†ŒλΌλ©΄, 우린 nextλ₯Ό ν˜ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄ λ˜λŠ”κ²λ‹ˆλ‹€! μ½”λ“œλ₯Ό 보도둝 ν•˜κ² μŠ΅λ‹ˆλ‹€.

λ¨Όμ €, 각 νŒ€ λ©€λ²„μ˜ books 배열을 λ°˜λ³΅ν•˜λŠ” μ œλ„ˆλ ˆμ΄ν„°λ₯Ό λ§Œλ“€λ„λ‘ ν•˜κ² μŠ΅λ‹ˆλ‹€. νŒ€ λ©€λ²„μ˜ books 배열을 ν•¨μˆ˜μ— μ „λ‹¬ν•˜κ³ , κ·Έ 배열을 μˆœνšŒν•˜κ³  각각의 책을 λ„˜κ²¨μ€λ‹ˆλ‹€!

generators and iterators 27

μ™„λ²½ν•˜λ„€μš”! 이제 clubMembers 배열을 μˆœνšŒν•˜λŠ” μ œλ„ˆλ ˆμ΄ν„°λ₯Ό λ§Œλ“€μ–΄μ•Ό ν•©λ‹ˆλ‹€. 우린 클럽 멀버 κ·Έ μžμ²΄μ— λŒ€ν•΄ μ‹ κ²½μ“Έ ν•„μš”κ°€ μ—†κ³ , κ·Έλ“€μ˜ μ±…λ“€λ§Œ μˆœνšŒν•˜λ©΄ λ©λ‹ˆλ‹€. iterateMembersλž€ μ œλ„ˆλ ˆμ΄ν„°μ—μ„œ κ·Έλ“€μ˜ 책을 λ„˜κ²¨λ°›κΈ° μœ„ν•΄ iterateBooks μ΄ν„°λ ˆμ΄ν„°λ₯Ό μœ„μž„ν•©μ‹œλ‹€!

generators and iterators 28

거의 λλ‚¬μ–΄μš”! λ§ˆμ§€λ§‰ λ‹¨κ³„λŠ” λΆν΄λŸ½μ„ μˆœνšŒν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. 이전 μ—μ œμ™€ 같이 뢁클럽 μžμ²΄μ— λŒ€ν•΄ μ‹ κ²½μ“Έ 건 μ—†κ³ , 클럽 λ©€λ²„λ§Œ(특히 κ·Έλ“€μ˜ 책을) ν™•μΈν•˜λ©΄ λ©λ‹ˆλ‹€. 이제 iterateClubMembers μ΄ν„°λ ˆμ΄ν„°λ₯Ό μœ„μž„ν•˜κ³  clubMembers 배열을 μ „λ‹¬ν•©μ‹œλ‹€.

generators and iterators 29

이런 λͺ¨λ“  것듀을 μˆœνšŒν•˜κΈ° μœ„ν•˜μ—¬ bookClub 배열을 iterateBookClubs μ œλ„ˆλ ˆμ΄ν„°μ— μ „λ‹¬ν•¨μœΌλ‘œμ¨ μˆœνšŒν•  수 μžˆλŠ” μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό μ–»μ–΄μ•Ό ν•©λ‹ˆλ‹€. μ΄λ²ˆμ—λŠ” μ΄ν„°λ ˆμ΄ν„°λΌλŠ” 의미둜 μ œλ„ˆλ ˆμ΄ν„° 객체λ₯Ό it 라고 ν•˜κ² μŠ΅λ‹ˆλ‹€.

generators and iterators 30

idκ°€ ev812인 책을 찾을 λ•ŒκΉŒμ§€ next λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•΄λ³΄μ£ .

λλ„€μš”! μš°λ¦¬λŠ” μš°λ¦¬κ°€ μ°ΎλŠ” 책을 μ°ΎκΈ° μœ„ν•˜μ—¬ λͺ¨λ“  데이터λ₯Ό μˆœνšŒν•˜μ§€ μ•Šμ•„λ„ λ©λ‹ˆλ‹€. κ·Έ λŒ€μ‹  우리의 μš”μ²­μ— 따라 데이터λ₯Ό μ°ΎλŠ”κ±°μ£ ! μˆ˜λ™μœΌλ‘œ 맀번 next λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•˜λŠ” 것은 νš¨μœ¨μ μ΄μ§€κ°€ μ•ŠμœΌλ‹ˆβ€¦κ·Έ λŒ€μ‹  ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄λ³΄μ£ !

ν•¨μˆ˜μ— μš°λ¦¬κ°€ 찾을 책에 λŒ€ν•œ idλ₯Ό id에 μ „λ‹¬ν•˜λ„λ‘ ν•©λ‹ˆλ‹€. λ§Œμ•½ value.idκ°€ μš°λ¦¬κ°€ μ°ΎλŠ” 것이라면 κ°„λ‹¨ν•˜κ²Œ 전체 valueλ₯Ό(책에 λŒ€ν•œ 객체)λ₯Ό λ°˜ν™˜ν•˜λ©΄ 되고, 그게 μ•„λ‹ˆλΌ idκ°€ λ§žμ§€ μ•Šμ„ μ‹œ nextλ₯Ό 계속 ν˜ΈμΆœν•˜λ©΄ λ©λ‹ˆλ‹€!

generators and iterators 32

λ¬Όλ‘  이건 μ•„μ£Ό μž‘μ€ λ°μ΄ν„°μ…‹μ΄μ§€λ§Œ, ꡉμž₯히 λ§Žμ€ μ–‘μ˜ 데이터λ₯Ό 닀룬닀고 μƒκ°ν•΄λ³΄μ„Έμš”. ν˜Ήμ€ λ”± ν•˜λ‚˜μ˜ κ°’λ§Œ μ°ΎκΈ° μœ„ν•΄ μš°λ¦¬κ°€ 뢄석해야할 슀트림이 μžˆλ‹€κ±°λ‚˜μš”. 보톡 μš°λ¦¬λŠ” 뢄석을 μ‹œμž‘ν•˜κΈ° μœ„ν•΄ 데이터셋 전체가 쀀비될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ €μ•Όν•˜μ£ . μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λΌλ©΄ 우린 κ°„λ‹¨ν•˜κ²Œ λ°μ΄ν„°μ˜ μž‘μ€ λ©μ–΄λ¦¬λ§Œ μš”μ²­ν•˜κ³ , 데이터λ₯Ό ν™•μΈν•˜κ³ , next λ©”μ†Œλ“œλ₯Ό ν˜ΈμΆœν•  λ•Œλ§Œ 값이 μƒμ„±λ˜κ²Œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€!


β€œλ„λŒ€μ²΄ 이게 뭐야” 라고 생각이 λ˜λ”λΌλ„ κ±±μ •λ§ˆμ„Έμš”. μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜λŠ” μ—¬λŸ¬λΆ„λ“€ μŠ€μŠ€λ‘œκ°€ ν™•μ‹€ν•œ μ‚¬μš© 예제λ₯Ό κ°–κ³  μ‚¬μš©ν•΄λ³Ό λ•ŒκΉŒμ§€ κ½€ ν—·κ°ˆλ¦΄κ±°μ˜ˆμš”! μ•½κ°„μ΄λ‚˜λ§ˆ 이해가 κ°€μ…¨κΈΈ 바라고 늘 κ·Έλ ‡λ“―: 질문이 μžˆμœΌμ‹œλ©΄ μ–Έμ œλ“  μ—°λ½μ£Όμ„Έμš”! πŸ˜ƒ