비동기는 동시가 아니라 순서의 문제다

jeongwon yun·2022년 10월 16일
0

Javascript Core

목록 보기
7/13

비동기를 async/await 으로 동기로 만들었다. => X

한번 비동기는 영원히 비동기이다.

콜백이라고 무조건 비동기가 아니다.

비동기 콜백이 비동기이고

동기 콜백은 동기이다.

setTimeout(() => {
	console.log('a');
}, 0);
setTimeout(() => {
	console.log('b');
}, 1000);
setTimeout(() => {
	console.log('c');
}, 2000);

setTimeout 은 비동기 함수이다.

backgroud: 운영체제나 JS 엔진 => JS 가 아니다 => 동시로 실행가능
M: 매크로 큐
m: 마이크로 큐

JS 는 싱글스레드라서 동시 개념이 없다.

background 에는 setTimeout의 타이머, 프로미스, 노드의 process.nextTick(), 네트워크 요청(AJAX), 이벤트리스너, 커스텀이벤트 등이 들어올 수 있다. (모두 비동기)

콜 스택에는 anonymous 먼저 바닥에 깔리고
setTimeout 이 실행되고 background에 타이머가 등록된다.
background 에서는 이 타이머가 동시에 시간을 체크해준다.
0초 뒤에 매크로 큐에 콜백 함수를 쌓인다.
1초 뒤, 2초 뒤 각각 매크로 큐에 쌓인다.
이 매크로 큐에 쌓인 함수는 anonymous까지 종료되고 콜 스택이 비었을 때 이벤트 루프에 의해 순서대로 콜 스택에 쌓이고 실행된다.

promise, process.nextTick => 마이크로 큐
나머지 => 매크로 큐

setTimeout 은 특정 초가 지나면 콜백함수를 매크로 큐에 넣는다.
이벤트리스너(클릭)은 클릭이 되면 콜백을 매크로 큐에 넣는다.
프로미스는 resolve 나 reject 되는 순간에 마이크로 큐에 넣는다.

만약 동시라면 우선순위는 마이크로 큐가 더 높다.
마이크로 큐에 있는 함수부터 콜 스택에 넣어준다.

마이크로 태스크 큐가 꽉 차있으면 영원히 매크로태스크 큐는 실행이 안 되게 된다.

setTimeout(() => {
	console.log('a');
}, 0);
setTimeout(() => {
	console.log('b');
}, 1000);
setTimeout(() => {
	console.log('c');
}, 2000);
Promise.resolve().then(() => {
	console.log('p');
});

p
a
b
c
이렇게 콘솔이 찍힌다.
프로미스가 더 우선시 된다.

0개의 댓글