이벤트 루프

ㅎㄱㅎ·2020년 11월 3일
0

이벤트루프

[call stack] ~~ event loop ~~ (web Api(setTimeout, Promise, requestAnimationFrame)) ~~ Task/ MicroTask / animationFrames

chrome 기준 규칙(브라우저마다 상이함)
http://sculove.github.io/blog/2018/01/18/javascriptflow/
https://blueshw.github.io/2018/01/28/tasks-microtasks-queues-and-schedules/
https://medium.com/@lydiahallie/javascript-visualized-promises-async-await-a3f1aad8a943

web api에 의해..
등록된 시간이 지난 후, setTimeout 에 등록된 callback을 Task에 등록
requestAnimationFrame 실행 후, requestAnimationFrame에 등록된 callback은 Animation frames에 등록
Promise가 resolve, reject 되면, Promise의 then에 등록된 callback은 MicroTask에 등록

  1. MicroTask에 callback이 있으면 event loop가 먼저 call stack으로 보냄
  2. MicroTask에 callback이 없다면 Animation frames에 등록된 callback이 있나 check
    2-1. animation frames에 등록된 callback이 있다면 event loop가 Task 보다 먼저 call stack으로 보냄
    2-2. animation frames에 등록된 callback이 없다면 event loop가 Task 에 등록된 callback을 call stack으로 보냄
  3. async 함수에서 await는 Task를 다 실행 후 자신의 resolve를 기다린다, resolve 되면 다음으로 넘어간다.
const promise = function(){
    return new Promise((resolve, rejct)=>{
        setTimeout(()=>{
            console.log("resolve")
            resolve(1)    
        }, 0)        
    })
}

async function TEST(){
    console.log("script start");
    setTimeout(function() {
      console.log("setTimeout");
    }, 0);
    await promise();
    Promise.resolve().then(function() {
      console.log("promise1");
    }).then(function() {
      console.log("promise2");
    });

    requestAnimationFrame(function() {
        console.log("requestAnimationFrame");
    })
    console.log("script end");        
}
TEST();

의 결과는

script start
setTimeout
resolve
script end
promise1
promise2
requestAnimationFrame

이다.

좀더 깊이 들여다 보자

async function TEST(){
	//event loop - 바로 실행
    console.log("script start"); 
    //task1 등록 - microtask가 비어 있으니 0초뒤 바로 실행
    setTimeout(function() {
      console.log("setTimeout");
    }, 0);   
    
    // setTimeout을 Task로 보낸 후 resolve를 기다린다
    // 이 말밖에 정리할 말이 없네요,, event loop에 await promise가 있으면
    // setTimeout이 작동 안할 것이고 ,, 
    // await가 붙으면 그냥 task로 가려나요 .. 왠지 그럴 것 같습니다 아래 예제를 더 보면
    // 이벤트 루프는 '현재 실행중인 태스크가 없을 때'(주로 호출 스택이 비워졌을 때) 
    // 태스크 큐의 첫 번째 태스크를 꺼내와 실행한다. 고 하네요 
    // 호출 스택이 안비워져 있어도 실행중인 태스크가 없다면 태스크를 꺼내와 실행 하는 
    // 모양입니다. 
    await promise();
    
    // microtask 1, 2 등록
    Promise.resolve().then(function() {
      console.log("promise1");
    }).then(function() {
      console.log("promise2");
    });
	// animation frame -> microtask 1, 2 resolve 후 호출
    requestAnimationFrame(function() {
        console.log("requestAnimationFrame");
    })
    //event loop 바로 실행
    console.log("script end");        
}

Promise microTask Queue이지만, resolve는 꼭 순차적으로 되는 것은 아니다.

const pr1 = function(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            console.log("pr1")
            resolve(1)
        }, 100)
    })
}
const pr2 = function(){
    return new Promise((resolve, reject)=>{
        setTimeout(()=>{
            console.log("pr2")
            resolve(2)
        }, 50)
    })
}




async function Test(){
    setTimeout(()=>{
        console.log('setTmeout')
    }, 100)
    await pr1()
    pr2()    
}

setTimeout
pr1
pr2

async function Test(){
    setTimeout(()=>{
        console.log('setTmeout')
    }, 100)
    pr1()
    pr2()    
}
pr2
pr1
setTimeout

profile
dog발자

0개의 댓글