Skip to content

iterator 와 generator

iforget edited this page May 1, 2020 · 1 revision

μ΄ν„°λ ˆμ΄ν„°(iterator)

  • μ§€κΈˆ μ–΄λ”” μžˆλŠ”μ§€ νŒŒμ•…ν•  수 있게 λ•λŠ” μ±…κ°ˆν”Ό 같은 κ°œλ…
  • μ΄ν„°λ ˆμ΄ν„°κ°€ λκΉŒμ§€ μ§„ν–‰ν•˜λ©΄ λ’€λ‘œ λŒμ•„κ°ˆ 수 μ—†μŒ
  • 독립적. μƒˆ μ΄ν„°λ ˆμ΄ν„°λ₯Ό λ§Œλ“€λ•Œλ§ˆλ‹€ μ²˜μŒμ—μ„œ μ‹œμž‘

next() :

  • λ‹€μŒ ν•­λͺ©μœΌλ‘œ λ„˜μ–΄κ°
  • value : ν•­λͺ©μ˜ κ°’
  • done : λ§ˆμ§€λ§‰ ν•­λͺ©μ„ 끝내면 true둜 λ°”λ€œ
const book = [
    '1 page',
    '2 page',
    '3 page',
];
 
const it = book.values(); // μ΄ν„°λ ˆμ΄ν„° 생성
 
console.log(it.next()); //{ value : '1 page', done: false }
console.log(it.next()); //{ value : '2 page', done: false }
console.log(it.next()); //{ value : '3 page', done: false }
console.log(it.next()); //{ value : undefined, done: true }
console.log(it.next()); //{ value : undefined, done: true }

μ΄ν„°λ ˆμ΄μ…˜ ν”„λ‘œν† μ½œ

  • λͺ¨λ“  객체λ₯Ό μ΄ν„°λŸ¬λΈ”(iterable)객체둜 λ°”κΏ€ 수 μžˆλ‹€
  • ν΄λž˜μŠ€μ— Symbol.iterator 심볼 λ©”μ„œλ“œκ°€ 있고 value와 done ν”„λ‘œνΌν‹°λ₯Ό κ°€μ§„ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” nextλ©”μ„œλ“œλ₯Ό κ°€μ§„ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” λ‚΄μš©μ„ κ΅¬ν˜„
class Log {
    constructor() {
        this.messages = [];
    }
 
    add(message) {
        this.messages.push({message, timestamp: new Date()});
    }
 
    [Symbol.iterator]() {
        let i = 0;
        const messages = this.messages;
        return {
            next() {
                if (i >= messages.length) {
                    return {value: undefined, done: true}
                }
                return {value: messages[i++], done: false}
            }
        }
    }
}
 
const log = new Log();
log.add('first');
log.add('second');
log.add('third');
 
for (let entry of log) {
    console.log(`${entry.message} @ ${entry.timestamp}`);
}

μ œλ„ˆλ ˆμ΄ν„°(generator)

  • μ΄ν„°λ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν•΄ μžμ‹ μ˜ 싀행을 μ œμ–΄ν•˜λŠ” ν•¨μˆ˜
  • 호좜 μ¦‰μ‹œ μ‹€ν–‰λ˜μ§€ μ•ŠμœΌλ©° μ΄ν„°λ ˆμ΄ν„°λ₯Ό λ°˜ν™˜ν•œλ‹€.
  • ν•¨μˆ˜μ˜ 싀행을 쀑간에 λ©ˆμΆ”μ—ˆλ‹€κ°€ λ‹€μ‹œ μž¬κ°œν•  수 μžˆλ‹€.
  • next() λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ œλ„ˆλ ˆμ΄ν„° ν•¨μˆ˜ λ°”λ””λ₯Ό μ‹€ν–‰ν•˜λ‹€κ°€ yieldλ₯Ό λ§Œλ‚˜λ©΄ λ°”λ‘œ μ€‘μ§€ν•˜κ³  yield된 κ°’ λ°˜ν™˜
  • function ν‚€μ›Œλ“œ 뒀에 μ• μŠ€ν„°λ¦¬μŠ€ν¬ (*)λ₯Ό λΆ™μž„
function* rainbow(){
    yield 'red';
    yield 'orange';
    yield 'yellow';
    yield 'green';
    yield 'blue';
    yield 'indigo';
    yield 'violet';
}
 
const it = rainbow();
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());
/*
result :
{ value: 'red', done: false }
{ value: 'orange', done: false }
{ value: 'yellow', done: false }
{ value: 'green', done: false }
{ value: 'blue', done: false }
{ value: 'indigo', done: false }
{ value: 'violet', done: false }
{ value: undefined, done: true }
*/
```javascript
### μ–‘λ°©ν–₯ 톡신
```javascript
function* interrogate(){
    const name = yield 'What is your name?';
    const color = yield 'What is your favorite color?'
    return `${name}'s favorite color is ${color}`;
}
 
const it = interrogate();
 
console.log(it.next());
console.log(it.next('Peter'));
console.log(it.next('Blue'));
  
result :
{ value: 'What is your name?', done: false }
{ value: 'What is your favorite color?', done: false }
{ value: 'Peter\'s favorite color is Blue', done: true }

μ œλ„ˆλ ˆμ΄ν„°μ™€ return

  • μ œλ„ˆλ ˆμ΄ν„°μ—μ„œ 리턴을 μ‚¬μš©ν•˜λ©΄ μœ„μΉ˜μ™€ 관계없이 done이 trueκ°€ 되고 value ν”„λ‘œνΌν‹°λŠ” 리턴이 λ°˜ν™˜ν•˜λŠ” 값이 됨
  • μ œλ„ˆλ ˆμ΄ν„°λ₯Ό μ‚¬μš©ν• λ•Œ done이 trueκ°€ 되면 value ν”„λ‘œνΌν‹°μ— μ‹ κ²½μ“°μ§€ μ•Šκ²Œλ¨ (ex. for...of λ£¨ν”„μ—μ„œ λ§ˆμ§€λ§‰ 리턴은 좜λ ₯λ˜μ§€ μ•ŠμŒ)
function* genFunc(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}
 
let gen = genFunc();
 
for(let it of gen){
    console.log(it);
}
function* genFunc(){
    yield 1;
    yield 2;
    yield 3;
}
 
let gen = genFunc();
 
console.log(gen.next());
console.log(gen.return(22));
console.log(gen.next());

Clone this wiki locally