JSConf Korea 2019
JSConf Korea를 다녀오다
  • JavaScript

1. 다마고치로 배우는 제너레이터

웹 프로젝트로 다마고치를 개발하면서 사용한 제너레이터에 대한 강연이었다.

Generator란?

Generator객체는 generator function으로부터 반환된 객체이다.
간단히 다시 작성해보면, javascript에서 function선언을 할 때
function* test() {} 과 같이 * 을 붙여주면 generator function이라는 함수를 선언할 수 있다. 그리고 이로부터 반환된 객체를 의미한다.

예를 들어보면 아래 코드와 같다.

function* generatorFunction() {
    yield 20;
}

const generator = generatorFunction();

yeild / next

yeild는 generator함수에서 순서를 나타낸다. 일반 함수와는 다르게 next()를 호출하기 전에는 yeild에서 일시정지한 상태로 기다린다. next()를 호출 시 yeild에서 기다리다가 다음 yeild를 실행한다.

일반 함수에서 callback을 기다리는 느낌과 비슷하다.

위의 예제의 소스에서 next()를 사용해보자

function* generatorFunction() {
    yield 20;
}

const generator = generatorFunction();
console.log(generator.next());

// 출력 : { value: 20, done: true }

만약 yeild가 2개 이상이라 다음 yeild가 또 있다면..

function* generatorFunction() {
    yield 20;
    yield 30;
}

const generator = generatorFunction();
console.log(generator.next());

// 출력 : { value: 20, done: false }

이와같이 다음 yeild이 있으므로 done값은 false이다.

2. Don’t block the event loop! 매끄러운 경험을 위한 자바스크립트 비동기 처리

코드를 좀 더 매끄럽게. 사용자에게 좀 더 부드럽게.
함수를 호출 할 때 Call Stack에서는 어떠한 일이 벌이질까?

a. Call Stack의 처리과정

function hello() {
    console.log('hello');
}

function helloPrint() {
    hello();
    console.log('print completed');
}

helloPrint();

위와 같은 예제가 있다고 생각해보자. 스택에서는 어떤 일이 일어날까?

1. main() 적치
2. helloPrint() 적치
3. hello() 적치
4. console.log('hello') 처리
5. console.log('hello') 완료
6. console.log('print completed') 처리
7. console.log('print completed') 완료
8. hello() 완료
9. helloPrint() 완료
10. main() 완료

이와같은 순서로 Stack에서 처리가 이루어질것이다.

Stack구조상 한개의 작업이 끝나야 다음 작업이 이루어지므로 위 1~10번 과정 중 하나라도 시간을 오래잡아먹는 잡업이 있다면 그 이후의 작업은 처리가 되지 못할것이다. 즉 웹이 죽는 현상이 발생할 수 있다.

b. Event loop에 대해 알아보자

setTimeout(() => {
    console.log('hello');
})

Promise.resolve().then(() => {
    console.log('JSConfKorea!!');
});

위의 예제를 살펴보자. setTimeout은 javascript에서 일정 시간 딜레이를 기다린 다음 실행하게 하는 함수이다. 위 예제에서는 시간을 지정하지 않았으므로 defalut값인 0이 들어간다.

그리고 그 바로 아래는 간단한 메세지를 출력하는 함수이다.

위의 예제의 실행결과를 예상해보자.

hello
JSConfKorea!!

0초후 실행이니 바로 메세지를 출력하고 그 다음 JSConfKorea!!가 출력될거라 예상할 수 있다.
Call Stack에서는 어떤일이 일어나는지 확인해볼 필요가 있다.

1. Call Stack에 setTimeout() 적치
2. Task에 hello 적치
3. Call Stack에 Promise.resolve().then() 적치
4. Microtasks에 JSConfKorea!! 적치
5. JSConfKorea!! 출력 
6. hello 출력

우리가 예상했던 출력순서와는 좀 다르다. 왜 그럴까?

Microtask는 새로운 Task의 개념으로 기존 Task에 영향을 받지 않고 Async로 실행되는 Task이다. Microtask로 실행되는 함수는 대표적으로 Promise callback, MutationObserver, process.nextTck이 있다.

아래의 JSConfKorea!!는 Promise로 실행되기 때문에 MicroTask로 실행되고, MicroTask는 Task보다 더 높은 실행 우선순위를 가진다. 따라서 hello보다 먼저 출력된다.
그래서 위의 예제에서 출력순서가 뒤바뀌는것을 볼 수 있다.

정리하며..

여러 가지 세션이 있었지만 그중 두 가지 내용에 대해 정리해보았다. 2번으로 설명한 내용에는 Task, MicroTask를 주목하여 클라이언트의 최적화에 대해 뒷장에 설명하고있는데 해당 부분도 공부해서 더 좋은 서비스를 만들 수 있다면 좋을 것 같다.

Reference

  1. https://www.slideshare.net/100003065728857/javascript-async-for-effortless-ux