본문 바로가기
우아한 테크코스

비동기 퀴즈

by 해-온 2023. 3. 20.

 

Q1. 왜 1->3->2 순으로 출력되는지 설명하시오.

console.log("1");
setTimeout(() => console.log("2"));
new Promise((resolve) => resolve()).then(() => {
  console.log("3");
});

A.

먼저, '스크립트' 태스크가 태스크 큐에 들어간다.

태스크 큐에서 이벤트 루프가 console.log('1')을 콜스택에 넣고 실행시킨다.

 

setTimeout이 콜스택으로 가고 Wep API가 이를 받아서 타이머를 실행시킨다.

타이머가 끝난 후 setTimeout의 콜백함수를 태스크 큐에 넣는다.

 

promise가 콜스택으로 가고, 콜백 함수를 마이크로 태스크 큐에 넣는다.

이벤트루프가 마이크로 태스크 큐에서 가장 오래된 태스크인 promise의 콜백함수를 가져와 콜스택에 넣는다.

 

promise 콜백 함수의 출력이 끝나고 태스크 큐에서 가장 오래된 태스크인 setTimeout의 콜백함수를 가져와 콜스택에 넣는다.

setTimeout 콜백 함수의 출력이 끝나면 콜스택이 비고 프로그램이 종료된다.

 


Q2. 아래의 함수의 결괏값이 도출되는지 설명하시오.

for (var i = 0; i < 10; i++) {
  setTimeout(() => console.log(i)); // 10이 10번 출력
}

A.

var는 함수 스코프이다.

스크립트 실행 태스크가 먼저 실행되면서 var가 for문 내에서 매번 생성되지 않는다.

따라서 for문을 돌며 i는 10으로 증가한다.

그 후 태스크 큐에 저장되어 있던 setTimeout의 콜백함수가 실행되면서 이미 10으로 증가된 i를 참조한다.

따라서 10이 10번 출력된다.

 

for (var i = 0; i < 10; i++) {
  (function (i) {
    setTimeout(() => console.log(i)); // 0 1 2 3 4 5 6 7 8 9
  })(i);
}

A.

for문 내부의 함수가 i 값을 인자로 받아 즉시 실행 함수로 바로 실행된다.

그리고 setTimeout 함수를 반환하는 클로저의 모습을 보여준다.

해당 함수는 태스크 큐로 이동하고 for문의 순회를 마치고 콜스택이 비워질 때 큐에 저장한 setTimeout 함수를 실행한다.

실행될 때마다 setTimeout 함수 내부의 콜백함수를 다시 큐에 담아둔다.

다시 한번 콜스택이 비워지면 큐에서 console.log 함수를 실행, 출력하게 된다.

이때 i의 값은 클로저의 특성으로 스코프체인을 타고 setTimeout 함수에서 i를 찾아본다.

해당 컨텍스트는 i 값이 없기 때문에 한 단계 더 상위 함수인 즉시 실행 함수에서 i 값을 참조하게 되어 i를 출력한다.


Q3. something 함수에서 getPopularMovies를 호출한 결괏값을 받아서 console에 출력하시오.

왜 이렇게 짜서 왜 이렇게 작동하는지 설명도 덧붙여야 합니다.

단, something 함수는 async 키워드를 붙일 수 없다.

 

async function getPopularMovies() {
  await new Promise((resolve) => setTimeout(resolve, 1000));
  return ["장화신은 고양이", "똑똑똑", "와칸다 포에버", "다이 하트", "플레인", "아바타: 물의 길"];
}

function something() {
  //✨✨✨✨✨✨✨✨✨✨✨✨✨✨ 수정 가능 영역
  //✨✨✨✨✨✨✨✨✨✨✨✨✨✨
}
something();

 

A.

function something(){
  getPopularMovies().then(console.log)
};

async가 붙은 함수는 return 값이 있더라도 promise를 반환한다.

따라서 then을 사용하면 promise가 이행됐을 때 resolve나 reject 된 값을 파라미터로 받아온다.

 


Q4. getPopularMovies 함수가 3초 이상 지연되면 "대기 시간이 오래 걸립니다"라는 오류 메시지를 콘솔로 출력하시오.

왜 이렇게 짜서 왜 이렇게 작동하는지 설명도 덧붙여야 합니다.

(단, 3초 이상 지연 시 getPopularMovies는 작업이 중단되거나 결괏값은 무시된다.)

console.error("대기 시간이 오래 걸립니다");

아래의 영역에 코드를 채워 넣고 왜 해당 코드를 넣으면 해결되는지 설명하시오.

const getPopularMovies = new Promise((resolve, reject) => {
  setTimeout(resolve, Math.random() * 4000 + 1000, "외부 API 접근한 결괏값");
});

// 아래에 답안을 작성하세요

 

A.

const getPopularMovies = new Promise((resolve) => {
  setTimeout(resolve, Math.random() * 4000 + 1000, '외부 API 접근한 결괏값');
});

const timeout = new Promise((resolve) => {
  setTimeout(resolve, 3000, '대기 시간이 오래 걸립니다');
});

Promise.race([getPopularMovies, timeout]).then(console.log);

promise race는 둘 이상의 promise 중 가장 먼저 처리된 결과를 반환한다.

 

각각의 promise는 마이크로 태스크 큐에 등록된다.

가장 먼저 처리된 결과를 반영하기 위해 promise.race는 마이크로 태스크 큐에서 대기 중인 promise 중, 가장 먼저 등록된 promise를 선택한다.

promise race()가 반환되면 남아 있는 promise는 취소된다.

 

'우아한 테크코스' 카테고리의 다른 글

레벨1 - 로또 게임 피드백  (0) 2023.04.03
레벨1 - 자동차경주 피드백  (0) 2023.04.03
HTML의 자식 요소 제거 방식  (0) 2023.03.20
innerText와 textContent의 차이  (0) 2023.03.20
🚗 단위 테스트 🚗  (0) 2023.02.08

댓글