본문 바로가기

JAVASCRIPT

<JAVASCRIPT> 제너레이터(Generator)란? / 제너레이터와 일반함수의 동작차이 / next()

 

 

 

 

 

면접을 보고나니 기본이 얼마나 중요한지 다시금 깨닫게 되었다ㅠㅠ 비슷한 기능을 구현하는 것은 인터넷에 뒤져보면 얼마든지 나온다. 하지만 에러가 발생했을 때 고치거나 로직을 변경해야할때 왜 이렇게 썼는지에 대해 말하기 위해서는 기본 개념이 정말... 정말 잘 잡혀있어야 한다는거.....

 

여튼 그래서 제너레이터가 무엇인가에 대해서 알아보자!

 

 

1. 제너레이터란?

- 일반함수는 하나의 리턴값만 반환하지만 제너레이터를 사용하면 여러개의 값을 필요에 따라 하나씩 반환(yield)할 수 있다.

 

 

그러니까 조건문처럼 길지 않지만 때에 따라 원하는 반환값이 나온다.

switch (age) {
    case age<=10 :
        var ticket = 10;
        break;

    case age > 10 :
        var ticket = 12;
        break;
        
    default:
        break;
}

 

이런식으로 작동하는게 아닐까? 라고 생각했는데 

제너레이터 함수를 호출하면

 

코드가 실행되는게 아니라

대신 실행을 처리하는 특별 객체, '제너레이터 객체'가 반환된다

 

 

 

 

띠용

 

엥? 이게 무슨말이야? 객체가 반환되면 실행은 어떻게 되는건데? 라고 생각이 들 것이다.

 

하지만 작동방식이 일반함수와 다르다! 어떻게 돌아가는지 예시를 보면 이해가 갈 것이다.

 

일단 제너레이터 함수를 만들려면 이 문법구조를 사용해야한다

 

function*

 

일반 함수를 선언할때 사용한 function에 *를 붙여준다.

 

 

예시

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
console.log(myFn);

 

 

아까 제너레이터 함수가 객체를 반환한다고 했는데 정말일까?

 

 

 

 

오.... 진짜 객체로 찍힌다. 그리고 중요한 것이

 

아직 함수가 실행되지 않았다. 함수 컨텍스트가 생성이 안되었다는 말이다.

 

 

2. 제너레이터의 next( )

- next()는 제너레이터의 주요 메서드 이며, next()를 호출하면 가장 가까운 yield <value> 문을 만날때 까지 계속 실행된다.

 

next() 는 딱봐도 다음으로 진행시키라는 메서드라고 직관적으로 알 수 있을 것이다.

그리고 항상 두 프로퍼티를 반환한다.

 

- value : 산출 값

- done : 함수의 실행이 끝났다면 true, 안끝났다면 false

 

 

예시 2

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
const first = myFn.next();
console.log(myFn);
console.log(first);

 

 

출력 결과값은 다음과 같다!

 

 

 

 

오.... next() 를 사용하니 처음만나는 yield의 값을 반환해줬다. 그리고 false가 뜬걸 보니 함수실행이 끝나지 않은 것을 알 수 있다. 아직 return을 만나지 못했기 때문!

 

예시3

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
const first = myFn.next();
const second = myFn.next();


console.log(first);
console.log(second);

 

 

 

 

 

 

 

 

그 다음 또 next()를 추가하니 이번엔 두번째 값이 나왔다. 그리고 함수실행이 완료되지 않았다고 뜬다.

 

 

 

그럼 더 추가하면? 

 

예시 4

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
const first = myFn.next();
const second = myFn.next();
const third = myFn.next();



console.log(first);
console.log(second);
console.log(third);

 

 

> 결과값

 

 

 

아.... 아직 함수 실행 상태가 false이다.

 

 

 

그럼 next()를 더 추가해보자

 

 

 

 

 

예시5

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
const first = myFn.next();
const second = myFn.next();
const third = myFn.next();
const final_ = myFn.next();


console.log(first);
console.log(second);
console.log(third);
console.log(final_);

 

 

 결과는...?

 

 

 

 

 

 

 

헉.... 드디어 결과값이 return 해줄 값과 함수 실행 상태가 true 라고 떴다!!

 

 

이예에에에에

 

 

 

 

흠.... 그럼 함수 실행이 완료 되었을 때 또 next()를 호출하면 어떻게 될까?

 

 

function* generatorEx(){
    yield 1;
    yield 2;
    yield 3;
    return 4;
}

let myFn = generatorEx();
const first = myFn.next();
const second = myFn.next();
const third = myFn.next();
const final_ = myFn.next();
const ddo = myFn.next();

console.log(first);
console.log(second);
console.log(third);
console.log(final_);
console.log(ddo);

 

 

> 결과값

 

 

오호.... 이번엔 value 가 undefined, 함수 실행 상태는 true가 나왔다.

 

 

next() 로 제너레이터에 있는 value 값과 함수의 상태 값을 출력할 수 있었다.

그런데 이렇게 일일이 next()를 계속 추가해줄 수도 없고 차라리 조건문을 쓰는게 낫지 않나? 라는 생각이 들었다.

 

 

 

그래서 이터러블이라는 것이 있다고 한다!

이터러블에 대해서는 다음 글에서 정리하겠다.

 

 

 

728x90