π Intro
μ§λ κΈμμ λ€λ£¨μλ Iterator μ μΈμ νκ² μ¬μ©λλ κ°λ μ€ νλκ° λ°λ‘ generator (μ λ€λ μ΄ν°) μ΄λ€. μ λ€λ μ΄ν°λ ES6μμ λμ λμ΄, μ½λ λΈλ‘μ μ€νμ μΌμ μ€μ§νλ€κ° νμν μμ μ μ¬κ°ν μ μλ νΉμν ν¨μμ΄λ€. μ΄λ² κΈμμλ generator funciton κ³Ό generatorμ νμ© λ°©λ²μ μ΄ν΄λ³΄κ³ μ νλ€.
β¨ Generator
MDN μμ μ μνλ generator λ "generator function (μ λ€λ μ΄ν° ν¨μ) λ‘λΆν° λ°νλ κ°μ΄λ©° iterable, iterator protocol μ μ€μνλ κ°" μ΄λ€. μμ μ μμμ νκΈ°λ Generator function μ μ£Όμ νΉμ§μ λ€μκ³Ό κ°λ€.
1. ν¨μ νΈμΆμ (caller) μκ² ν¨μ μ€νμ μ μ΄κΆμ μλ(yield)ν μ μλ€.
μΌλ° ν¨μλ νΈμΆ μ μ μ΄κΆμ΄ ν¨μμκ² λμ΄κ°κΈ° λλ¬Έμ μ½λκ° μΌκ΄ μ€νλλ©°, νΈμΆμλ μ€νμ μ μ΄ν μ μλ€. νμ§λ§ generator function μ νΈμΆμκ° ν¨μ μ€νμ μΌμ μ€μ§νκ±°λ μ¬κ°μν¬ μ μλ€. μ΄λ₯Ό ν¨μμ μ μ΄κΆμ μλ (yield) νλ€κ³ νννλ€.
2. ν¨μ νΈμΆμμ ν¨μμ μνλ₯Ό μ£Όκ³ λ°μ μ μλ€.
μΌλ° ν¨μλ νΈμΆ μ 맀κ°λ³μλ₯Ό ν΅ν΄ μΈλΆμμ κ°μ μ£Όμ λ°κ³ , μΌκ΄ μ€ννμ¬ κ²°κ³Όκ°μ λ°ννλ€. νμ§λ§ generator function μ νΈμΆμμκ² μνλ₯Ό μ λ¬νκ³ , μ λ¬λ°μ μ μλ€.
3. νΈμΆ μ generator λ₯Ό λ°ννλ€.
generator ν¨μ νΈμΆ μ μΌλ°μ μΈ κ°μ λ°ννλ κ²μ΄ μλλΌ iterable μ΄λ©΄μ λμμ iterator μΈ generator κ°μ²΄λ₯Ό λ°ννλ€.
π‘ Recap: λ³΅μ΅ ν¬μΈνΈ
Iterable μ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ€.
1. Symbol.iterator λ₯Ό νλ‘νΌν° ν€λ‘ μ¬μ©ν λ©μλλ₯Ό ꡬννλ€
2. Symbol.iterator λ₯Ό νλ‘ν νμ 체μΈμ ν΅ν΄ μμλ°λλ€
Iterator λ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ€.
3. next λ©μλ μμ
4. next λ©μλμ κ²°κ³Ό κ°μ²΄μ done, value νλ‘νΌν°λ₯Ό μμ
λ°λΌμ generator κ°μ²΄ μμ Symbol.iterator λ₯Ό μμλ°μΌλ©° value, done νλ‘νΌν°μ next λ©μλλ₯Ό μμ νλ€. νμ§λ§ μ€μν μ μ, generator λ iterator μλ μλ π return, throw λ©μλλ₯Ό κ°λλ€λ κ²μ΄λ€.
μμ μΈ κ°μ§ νΉμ§μ λμ± μ μ΄ν΄νκΈ° μν΄μλ generator functionμ μ μΈ λ°©λ²κ³Ό ꡬμ±μ μ΄ν΄λ³΄μμΌ νλ€. μ°μ , function* ν€μλλ‘ ν¨μλ₯Ό μ μΈνκ³ λ΄λΆμ yield ννμμ ν¬ν¨νλ©΄ generator function μ΄ λλ€. λ©μλλ‘ μ μΈν λλ * νμλ§ ν΄ μ£Όλ©΄ λλ€.
// Generator functions
function* genFunc() {
yield 1;
}
const obj = {
* genFunc() {
yield 1;
}
}
class Test {
* genFunc() {
yield 1;
}
}
// Check for methods
console.log('next' in genFunc()) // true
console.log('throw' in genFunc()) // true
β νμ΄ν ν¨μλ‘λ generator function μ μ μν μ μλ€.
β new μ°μ°μμ ν¨κ» μμ±μ ν¨μλ‘ νΈμΆν μ μλ€.
β¨ Generator μ λμ λ°©μ
μμ μΈκΈνλ generator μλ next λ©μλμ λλΆμ΄ κ³ μ ν yield ννμκ³Ό throw, return λ©μλλ₯Ό κ°λλ€. μμ λ₯Ό ν΅ν΄μ μ½κ² generator μ μλ λ°©μμ νμΈν μ μλ€.
// iterator μμλ done μ 쑰건μ λΆν©νλ μκ° true λ‘ μ νλλ€.
const iterFunc = {
[Symbol.iterator]() {
let cur = 1;
const max = 5;
return {
next() {
return {value: cur++, done: cur > max + 1}
}
}
}
}
const test = iterFunc[Symbol.iterator]()
console.log(test.next()) // {value: 1, done: false}
console.log(test.next()) // {value: 2, done: false}
console.log(test.next()) // {value: 3, done: false}
console.log(test.next()) // {value: 4, done: false}
console.log(test.next()) // {value: 5, done: false}
console.log(test.next()) // {value: 6, done: true}
console.log(test.next()) // {value: 7, done: true}
console.log(test.next()) // {value: 8, done: true}
// generator μμλ λ§μ§λ§ yield κ°κΉμ§ λ°νν λ€μμΌ done μνλ₯Ό true λ‘ μ ννλ€.
function* genFunc() {
yield 1;
yield 2;
yield 3;
}
const gen = genFunc();
console.log(gen.next()) // {value: 1, done: false}
console.log(gen.next()) // {value: 2, done: false}
console.log(gen.next()) // {value: 3, done: false}
console.log(gen.next()) // {value: undefined, done: true}
console.log(gen.next()) // {value: undefined, done: true}
console.log(gen.next()) // {value: undefined, done: true}
// generator μ return λ©μλλ₯Ό νΈμΆνλ©΄ μ λ¬λ°μ κ°μ value κ°μΌλ‘, true λ₯Ό done κ°μΌλ‘ κ°λ iterator result object (μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄) λ₯Ό λ°ννλ€.
console.log(gen.return('Ha')) // {value: 'Ha', done: true}
// throw λ₯Ό μ¬μ©νκΈ° μν΄μλ generator function μ΄ μλ¬λ₯Ό μ‘μ(catch)μ€μΌ νλ€.
// throw λ©μλλ₯Ό νΈμΆνλ©΄ undefined λ₯Ό value κ°μΌλ‘, true λ₯Ό done κ°μΌλ‘ κ°λ iterator result object (μ΄ν°λ μ΄ν° 리μ νΈ κ°μ²΄) λ₯Ό λ°ννλ€.
function* genFunc1() {
try {
yield 1;
yield 2;
yield 3;
} catch (e) {
console.error(e);
}
}
const gen1 = genFunc1();
console.log(gen1.next()) // {value: 1, done: false}
console.log(gen1.throw('Error!')) // Error!, {value: undefined, done: true}
console.log(gen1.next()) // {value: undefined, done: true}
generator λ μμ μ½λ μμ μμ λ³Έ κ²κ³Ό κ°μ΄ yield ν€μλμ next λ©μλλ₯Ό ν΅ν΄ μ€νμ μ€μ§νλ€κ° μ¬κ°ν μ μλ€. μμ μμ μμ generator function μ genFunc μ genFunc1 μ΄λ©°, μ΄λ₯Ό νΈμΆνμ¬ λ°νλ generator κ°μ²΄κ° λ°λ‘ gen κ³Ό gen1 μ΄λ€. λ°λΌμ next, return λ±μ λ©μλλ₯Ό κ°λ κ² μμ gen κ³Ό gen1 μ΄λ€.
console.log('next' in genFunc) // false
console.log('next' in gen) // true
console.log('return' in genFunc) // false
console.log('return' in gen) // true
yield ν€μλμ μν μ νΈμΆμμκ² ννμμ νκ° κ²°κ³Όλ₯Ό λ°ννλ κ², λλ ν¨μμ μ€νμ μΌμ μ€μ§μν€λ κ²μ΄λ€.
π νκ° κ²°κ³Όμ λ°ν
μμ μμ μμ yield λ₯Ό νΈμΆν νΈμΆμλ gen κ³Ό gen1 μ΄λ©°, λ°λΌμ μ¬κΈ°μ λ°νλ κ°μ΄ μ μ₯λκ² λλ€. μ΄ λ λ°νλλ κ°μ value μ done νλ‘νΌν°λ₯Ό κ°λ iterator result object μ΄λ€.
π ν¨μμ μ€νμ μΌμ μ€μ§
next λ©μλλ₯Ό νΈμΆνλ©΄ yield ννμκΉμ§ μ€νλκ³ μΌμ μ€μ§λλ€. μ΄λ ν¨μμ μ μ΄κΆμ΄ νΈμΆμμκ² μλλλλ°, μ΄ λ§μ μλ―Έλ νΈμΆμκ° νμν λκΉμ§ ν¨μλ₯Ό μΌμ μ€μ§ μνλ‘ λμλ€κ° νμν λ μ€νμ μ¬κ°ν μ μλ€λ κ²μ΄λ€.
λ νλ μ€μν νΉμ§μ, next() μμ λ€μ΄κ°λ μΈμ (μ λ¬μΈμ) μ νΉμ§μ΄λ€. next λ©μλμ λ€μ΄κ°λ μΈμλ yield ννμμ ν λΉλ°λ λ³μμ ν λΉλλ€. (β μ£Όμ : yield μ νκ° κ²°κ³Όκ° ν λΉλλ κ²μ΄ μλλ€! )
function* genFunc() {
// 첫 next νΈμΆ μ μ¬κΈ°μ μ€ν μ€λ¨
// value μλ 1μ΄ λ€μ΄κ°λ©° x μλ μ무κ²λ ν λΉλμ§ μμ
// ν΄λΉ ννμμ λ€μ next νΈμΆ μ μλ£λ¨
const x = yield 1;
// λλ²μ§Έ next νΈμΆ μ μ λ¬λλ μΈμλ x μ ν λΉλ¨
// yield ννμ μ€ν ν μ€λ¨, value μλ x + 10 λ€μ΄κ°, y μλ μ무κ²λ ν λΉλμ§ μμ
// ν΄λΉ ννμμ λ€μ next νΈμΆ μ μλ£λ¨
const y = yield (x + 10);
// μΈλ²μ§Έ next νΈμΆ μ x + 10 μ κ²°κ³Όκ° y μ ν λΉλ¨
// λ μ΄μμ yield κ° μμΌλ―λ‘ ν¨μκ° λκΉμ§ μ€νλ¨
// return κ°μ value μ λ€μ΄κ°λ©°, done μ true λ‘ μ ν
// return μ λ³λ€λ₯Έ μλ―Έκ° μμΌλ©° μ’
λ£ν λ μ¬μ©λ¨
return x + y;
}
const gen = genFunc();
// 첫λ²μ§Έ next μ¦ν μμλ μΈμλ₯Ό λ£λλΌλ 무μλλ€.
console.log(gen.next()) // {value: 1, done: false}
// x μ 10 μ κ°μ΄ ν λΉλ¨ (μ무 κ°λ λ£μ§ μλλ΄λ³ NaN μ΄ value λ‘ λ°ν)
console.log(gen.next(10)) // {value: 20, done: false}
// y μ 30 μ κ°μ΄ ν λΉλ¨
console.log(gen.next(30)) // {value: 40, done: true}
generator function μ ν΅μ¬μ next μ yield λ₯Ό ν΅ν΄ ν¨μ νΈμΆμμ ν¨μμ μνλ₯Ό μ£Όκ³ λ°μ μ μλ κ²μ΄λ€.
β¨ μ°Έκ³ μλ£
- λͺ¨λ μλ°μ€ν¬λ¦½νΈ Deep Dive (μν€λΆμ€)
- MDN
'π» DEV > Javascript & NodeJS' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
[JS] 0.1 + 0.2 !== 0.3 μΈ μ΄μ (1) | 2022.01.09 |
---|---|
[JavaScript] ν΄λμ€ (Class) (0) | 2021.12.12 |
[Javascript] Iterable (μ΄ν°λ¬λΈ) (0) | 2021.10.13 |
[Javascript] ν΄λ‘μ (Closure) (0) | 2021.10.06 |
[Javascript] μ€ν 컨ν μ€νΈ (Execution Context) μ μμ€μ½λ (0) | 2021.09.28 |
λκΈ