개발언어/JavaScript

[JavaScript] 이벤트 루프

JiWonSon 2022. 1. 5. 09:41
  • 자바스크립트 특징
  1. ‘단일 스레드’ 기반언어 → 동시에 하나의 작업만을 처리 가능
  2. 동시에 여러가지 작업을 처리하기 위해서 → 이벤트 루프 사용

따라서, 이벤트 루프를 이용해 비동기 방식으로 동시성을 지원

ex)

function delay() {
for (var i = 0; i < 100000; i++);
}
function foo() {
    delay();
    bar();
    console.log('foo!');// (3)
}
function bar() {
    delay();
    console.log('bar!');// (2)
}
function baz() {
    console.log('baz!');// (4)
}

setTimeout(baz, 10);// (1)
foo();

→ setTimeout함수 이벤트 요청 후 스택에서 제거

→ foo함수 스택에 추가 > bar > foo > baz

→ 코드 실행 중, 10초가 지나면 baz를 바로실행 x , 태스트 큐에 추가 (대기중인거임)

 

 

** 태스트 큐?

콜백 함수들이 대기하는 큐형태의 배열

 

 

** 이벤트 루프?

호출 스택이 비워질 때마다 큐에서 콜백 함수를 꺼내와 실행하는 역할

ex2)

function delay() {
for (var i = 0; i < 100000; i++);
}
function foo() {
    delay();
    console.log('foo!');
}
function bar() {
    delay();
    console.log('bar!');
}
function baz() {
    delay();
    console.log('baz!');
}

setTimeout(foo, 10);
setTimeout(bar, 10);
setTimeout(baz, 10);

→ setTimeout 함수 세번 호출 후 호출 스택 비움

→ 10초 후 foo, bar, baz 함수가 순차적으로 태스크 큐에 추가

→ foo 함수가 태스트 큐에 들어오자마자 호출 스택이 비어 있으므로 foo를 실행해서 호출 스택에 추가 > foo 함수 끝나고 호출 스택 비워지면 bar 실행 > baz 반복...

 

 

 

  • setTimeout 함수는 콜백 함수를 바로 실행하지 않고 태스크 큐에 추가한다.
setTimeout(function() {
    console.log('A');
}, 0);
console.log('B');

→ 실행 순서 ‘B’ , ‘A’

 

 

 

  • 프라미스(Promise)와 이벤트 루프
setTimeout(function() {// (A)
		console.log('A');
}, 0);
Promise.resolve().then(function() {// (B)
		console.log('B');
}).then(function() {// (C)
		console.log('C');
});

→ 실행 순서 ‘B’, ‘C’, ‘A’

 + 프라미스는 마이크로태스크를 사용하기 때문

 

 

 

** 마이크로태스크란?

일반 태스크보다 더 높은 우선순위를 갖는 태스크/ 대기중인 태스크가 있더라도 먼저 실행됨

‘B’는 태스크 큐가 아닌 마이크로 태스크 큐에 추가됨