호출스택 : 함수가 실행되는 공간(동기, 비동기)
백그라운드 : 비동기 함수가 저장되는 공간
태스크 큐 : 비동기 함수들의 실행 순서를 정하는 공간
이벤트 리스너: 태스크 큐에서 지정된 순서대로 하나씩 호출스택에 올려준다.
동기 함수들은 "호출스택"에 쌓여 순서대로 실행 및 종료 후 호출스택을 비워준다.
비동기 내부에 동기 함수가 있다면, 무조건 동기 먼저 실행 후 비동기는 백그라운드에 저장
비동기는 무조건 백그라운드에 먼저 저장. 타이머가 0초라도 무조건 백그라운드에 저장되어 동기 함수 종료 후 실행
비동기 함수들은 "백그라운드"에 저장이 되고,
모든 동기 함수들의 실행 종료 후 "호출스택"이 비어 있으면
"백그라운드"에 저장 되있던 비동기함수들이 "태스크 큐"로 이동되어
실행 순서를 지정받고
"이벤트 루프"에 의해 "태스크 큐"에서 "호출스택"으로 하나 씩 이동하며 비동기 함수가실행된다.
이벤트 함수 + setTimeout()
동기 함수인 startGame()에 의해 생성된
click 이벤트 리스너 onClickCard() 12개 를 ( "백그라운드"에 적재되어 있는 상황)
4번 클릭함으로써 "백그라운드"에서 "태스크 큐"에 4번 쌓인다.
"호출스택"에 하나 씩 이동 되며 내부의 타이머 비동기 함수를 "백그라운드"에 저장하며 종료.
"태스크 큐"에 적재된 4개의 onClickCard 이벤트 리스너가 전부 실행되고 종료,
호출스택이 비게 되면
"백그라운드"에 적재된 비동기 타이머 함수인 setTimeout 4개가 타이머 시간을 마친 뒤 "태스크 큐"로 이동 되고 하나씩 "호출스택"에서 실행.
두 번째 실행에서 clicked = []; 배열을 초기화 함으로
세, 네 번째에선 더이상 지울 clicked 배열 값이 없으니
나머지 2개의 타이머에선 remove('flipped');를 하지 못하고 종료
문제
function aaa() {
setTimeout(() => {
console.log('d');
}, 0);
console.log('c');
}
setTimeout(() => {
console.log('a');
aaa();
}, 0);
setTimeout(() => {
aaa();
console.log('b');
}, 0);
정답 : a, c, c, b, d, d