Section 14. 자바스크립트 비동기의 개념과 타임아웃
프로그래밍에서 동기란?
한 작업이 끝날때까지 다른 작업이 수행되지 않는 것을 말한다.
그렇다면 비동기란?
한 작업이 진행중이더라도 다른 작업들을 수행할 수 있는 것을 말한다.
특정 코드가 끝날때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것을 의미한다.
setTimeout 함수
- 첫 번째 인자로 넣은 콜백 함수를 두 번째 인자로 넣은 수 만큼의 밀리초 후 실행하는 함수이다.
- Web API, Node.js 등 자바스크립트 환경의 기능이지 언어의 기능이 아니다.
setTimeout(() => {
console.log('타임아웃!');
}, 1000); //1초 후 타임아웃!이 출력된다
비동기 asynchronous 코드
동기 synchronous 코드와는 달리, 코드가 순서대로 실행되지 않는다.
console.log('하나');
setTimeout(() => {
console.log('둘');
}, 1000); // 💡 0으로 바꿔 다시 실행해 볼 것
console.log('셋');
//하나
//셋
//둘
동기식이면 하나 둘 셋 순서대로 출력이 되야 한다. 하지만 setTimeout을 사용하여 '둘'의 출력을 1초 후로 출력되게 설정을 했기 때문에 '둘'의 출력이 가장 늦게 되었다.
정리하자면 다음과 같다
- 일반적으로 타임아웃, 네트워크 요청 등 시간이 걸리는 작업에 사용된다.
- 당장 할 수 있는것은 하고 시간이 걸리는 작업은 뒤로 미룬다.
1초 ~ 1.5초 사이 무작위 시간안에 도착하는 달리기 경주 예제가 있다.
function doRace (num, name) {
console.log(`👟 ${num}번 ${name} 출발`);
setTimeout (() => {
console.log(`🚩 ${num}번 ${name} 도착`);
}, 1000 + Math.random() * 500);
}
'철수,영희,돌준,정아,길돈'
.split(',')
.forEach((itm, idx) => doRace(++idx, itm));
출력 결과는 할 때마다 다르겠지만 우선은 어떻게 해서 이런 결과가 나오에 됐는지 이해를 할 필요가 있다.
일단 인덱스 번호가 순차적으로 증가하면서 doRace함수가 실행되니 ~~출발 이라는 출력문은 순서대로 실행이 되는 것을 볼 수 있다. 문제는 ~~도착 이라는 출력문이 순서대로 출력되지 않았다.
이것을 그림으로 설명을 하자면 다음과 같다
1.
기본적으로 자바스크립트는 싱글쓰레드로 실행을 한다.
2.
싱글쓰레이드로 실행하지만 자바스크립트 실행 환경이 마치 쓰레드가 여러개인 것처럼 작동 할 수 있게 해준다.
실행시점에 도착하면 동기 코드는 실행된다.
비동기 콜백 코드는 환경(Web API 등) 으로 넘겨준다.
3.
자바스크립트의 실행 환경 덕분에 여러 작업들이 동시 다발적으로 실행이 될 수 있다.
4.
작업들이 완료가 되면 완료가 된 순서대로 태스크 큐 로 보내진다.
5.
테스크 큐로 넘겨진 작업들은 이벤트 루프 를 통해서 다시 자바스크립트 실행 도로에 올라가게 된다(싱글쓰레드).
이런 작업들은 동기 코드가 모두 실행된 다음에 진행된다. 따라서 setTimeout의 지연시간을 0으로 해도 나중에 실행되는 것이다.