[JS] Generator 로그 순서 이해하기

generator에대해 공부하다가 generator 객체는 어떤 식으로 출력이 되는지 궁금했다.

그래서 콘솔에 로그를 찍어보았는데 로그가 찍히는 순서가 예상과 달라 고민에 빠졌다..

 

const addCoffee = function(prevName, name) {
    setTimeout(function() {
        coffeeMaker.next(prevName ? prevName + ", " + name : name);
    }, 100);
};

const coffeeGenerator = function* () {
    const espresso = yield addCoffee("", "에스프레소");
    console.log(espresso);
    
    const americano = yield addCoffee(espresso, "아메리카노");
    console.log(americano);
    
    const mocha = yield addCoffee(americano, "카페모카");
    console.log(mocha);
    
    const latte = yield addCoffee(mocha, "카페라떼");
    console.log(latte);
};

const coffeeMaker = coffeeGenerator();
coffeeMaker.next();

우선 기존 코드는 위와 같다.

 

let count = 0;

const addCoffee = function(prevName, name) {
    setTimeout(function() {
        console.log(count, coffeeMaker.next(prevName ? prevName + ", " + name : name));
        console.log("여기는?", count++);
    }, 500);
};

const coffeeGenerator = function* () {
    const espresso = yield addCoffee("", "에스프레소");
    console.log(espresso);
    
    const americano = yield addCoffee(espresso, "아메리카노");
    console.log(americano);
    
    const mocha = yield addCoffee(americano, "카페모카");
    console.log(mocha);
    
    const latte = yield addCoffee(mocha, "카페라떼");
    console.log(latte);
};

const coffeeMaker = coffeeGenerator();
console.log("coffeMaker.next! => ", coffeeMaker.next());

이해를 위해 setTimeout()에서 .next() 를 호출하는 라인, 호출 후에 로그를 찍었다.

전역변수로 count를 선언해 몇번째로 출력된 로그인지 확인할 수 있도록 했다.

 

처음 예상으로는 coffeGenerator 내부에서의 console.log()가 문제없이 값을 받아오고있으니 addCoffee() 내부의 로그들이 먼저 찍히고, 에스프레소 등 coffeeGenerator의 로그가 나중에 찍힐 것이라 예상했는데 그 반대였다. 한시간정도 검색도 해보고 로그 찍는 방식도 바꿔가면서 고민을 해보다가 튜터님께 질문을 드렸다.

 

이렇게 출력되는 이유는 지금 작성된 코드가 비동기적으로 실행되기 때문이다!!!!

비동기 파트를 공부하고 있으면서 이 점을 고려하지 못했다..

 

정리하자면

1) coffeeMaker.next()로 yield를 만날 때까지 iterator 내부 동작이 실행된다.

2) yield를 만나 addCoffee를 실행한다.

3) addCoffee 내부의 coffeeMaker.next()로 iterator 내부 동작이 다시 yield를 만날 때까지 실행되기 시작한다!

4) 동시에 addCoffee 내부의 나머지 동작 또한 실행된다.

 

3,4 과정이 동시에 일어난다는 고려를 하지 못하고 yield 에 들어왔으니 addCoffee가 끝날 때까지 기다려야한다는 생각에 계속 사고가 묶여있었다..