동기와 비동기
먼저 작성한 코드가 늘 먼저 끝나지는 않는다는 것을 봅니다.
먼저 적은 것이 먼저 끝나지 않습니다
여기까지의 코드는 위에서 아래로 차례대로 실행됐습니다. 한 줄이 끝나야 다음 줄이 시작합니다. 이것을 동기(synchronous) 라고 합니다.
그런데 서버에서 데이터를 가져오는 일은 오래 걸립니다. 그동안 아무것도 못 하고 멈춰 있으면 화면이 얼어붙습니다. 그래서 오래 걸리는 일은 맡겨 두고 다음 줄을 먼저 실행합니다. 이것이 비동기(asynchronous) 입니다.
차례를 예측해 보세요
실행하기 전에 어떤 차례로 나올지 먼저 생각해 보세요.
console.log("첫째"); setTimeout(() => { console.log("셋째"); }, 1000); console.log("둘째");
setTimeout 은 나중에 할 일을 맡겨 두는 함수입니다.
첫 인자가 할 일(함수), 둘째가 기다릴 밀리초입니다. 맡기고 나서 바로 다음 줄로
넘어갑니다.
0밀리초여도 마지막입니다
console.log("첫째"); setTimeout(() => console.log("셋째"), 0); console.log("둘째");
0 을 적어도 지금 실행 중인 코드가 모두 끝난 뒤에
실행됩니다. 맡긴 일은 줄을 서서 기다리고, 지금 하던 일이 끝나야 차례가 옵니다.
그래서 setTimeout 의 시간은 정확히 그때가
아니라 그때 이후 가장 빠른 때 입니다.
여러 개를 맡기면
setTimeout(() => console.log("300"), 300); setTimeout(() => console.log("100"), 100); setTimeout(() => console.log("200"), 200); console.log("먼저");
적은 차례가 아니라 시간이 짧은 것부터 나옵니다. 맡긴 일들은 서로 기다리지 않습니다.
동기 코드는 화면을 멈춥니다
아래처럼 오래 도는 반복문은 그동안 아무것도 못 하게 만듭니다. 버튼도 눌리지 않고 화면도 그려지지 않습니다.
const end = Date.now() + 3000; while (Date.now() < end) { // 3초 동안 화면이 멈춥니다 } console.log("끝");
이 예제에는 실행 단추가 없습니다. 실행하면 3초 동안 아무것도 하지 못하고, 이 화면의 실행기는 그것을 무한 루프로 보아 중단합니다(1.10).
서버 요청도 이만큼 오래 걸립니다. 그것을 동기로 기다렸다면 요청할 때마다 화면이 얼어붙었을 것입니다. 비동기가 필요한 까닭이 이것입니다.
맡긴 일 취소하기
const cancelled = setTimeout(() => console.log("이 줄은 나오지 않습니다"), 100); clearTimeout(cancelled); const kept = setTimeout(() => console.log("이 줄만 나옵니다"), 200);
setTimeout 은 번호를 돌려줍니다. 그 번호로
clearTimeout 을 부르면 맡긴 일이 취소됩니다.
처음에 자주 걸리는 것
아직 실행되지 않았으므로 값이 없습니다. 이것이 비동기에서 가장 많이 하는 실수이고, 5.3 부터 그것을 다루는 방법을 배웁니다.
let result;
setTimeout(() => { result = "값"; }, 100);
console.log(result); // undefined 입니다
2.6 · 4.5 에서 본 것과 같습니다. 괄호를 붙이면 그 자리에서 실행됩니다.
setTimeout(hello(), 100); // 지금 실행됩니다 setTimeout(hello, 100); // 이렇게 적습니다
100 은 "100밀리초 뒤" 가 아니라 "100밀리초 뒤부터
가능한 때" 입니다. 앞의 코드가 오래 돌면 더 늦어집니다.
직접 해보기
아래 코드의 출력 차례를 먼저 적어 보고, 편집기에 넣어 확인하세요.
0.2초 간격으로 1 부터
3 까지 출력하세요. 반복문 안에서
setTimeout 을 사용하면 됩니다.
i 에 따라 다르게 주면 됩니다.이 단원의 정리
- 오래 걸리는 일은 맡겨 두고 다음 줄을 먼저 실행합니다.
setTimeout은 나중에 할 일을 맡깁니다.- 시간이
0이어도 지금 코드가 끝난 뒤에 실행됩니다. - 맡긴 일들은 서로 기다리지 않고, 시간이 짧은 것부터 나옵니다.
- 맡긴 일의 결과를 바로 아래에서 읽을 수 없습니다. 5.3 부터 그 방법을 배웁니다.