비동기 처리를 이용하면 오래 걸리는 작업이 종료될 때까지 기다리지 않고, 다음 작업을 수행하는 등 유연한 프로그래밍이 가능하다.
자바스크립트에서 코드는 기본적으로 작성한 순서에 따라 위에서 아래로 순차적으로 실행된다. 이처럼 순차적으로 코드를 실행하는 것을 ‘동기’라고 한다. 동기적으로 동작하는 코드는 작성된 순서에 따라 작업이 진행되므로 작업의 흐름을 파악하기 쉽다. 그런데 오래 걸리는 작업을 빨리 끝날 작업보다 먼저 실행하게 되면 지연 문제가 생긴다. 이런 문제를 해결하려면 오래 걸리는 작업을 빨리 끝날 작업과 관계없이 별도로 진행하면 된다. 이렇듯 특정 작업을 다른 작업과 관계없이 독립적으로 동작하게 만드는 것을 ‘비동기’라고 한다.
예를 들어, 함수 setTimeout
을 이용하면 작업을 비동기적으로 처리할 수 있다.
setTimeout(function () { ①
console.log("1번!");
}, 3000);
console.log("2번!");
함수 setTimeout
은 비동기적으로 동작하는 함수다. 따라서 setTimeout
이 종료될 때까지 기다리지 않고 바로 다음 코드를 실행할 수 있다. 이렇듯 비동기 작업은 동기 작업과는 달리 작업의 실행 순서와 완료 순서가 일치하지 않는다.
다음 예시를 통해 콜백 함수로 비동기 작업을 처리하는 방법을 알아본다.
function double(num) {
setTimeout(() => {
const doubleNum = num * 2;
console.log(doubleNum);
}, 1000);
}
double(10); // 20
이 함수는 1초를 기다린 다음, 전달한 인수에 2를 곱해 콘솔에 출력하는 함수다. 그런데 이때 함수 double
의 결과를 반환하게 하려면 어떻게 해야 할지 살펴본다.
function double(num) {
return setTimeout(() => {
const doubleNum = num * 2;
return doubleNum;
}, 1000);
}
const res = double(10);
console.log(res);
// 알 수 없는 숫자
이 코드를 실행하면 20이 아닌, 알 수 없는 숫자가 출력된다. 이는 반환 값이 함수 setTimeout
에서 인수로 전달한 콜백 함수가 반환하는 것이 아니라, 타이머의 식별 번호가 반환되었기 때문이다. 함수 setTimeout
은 타이머의 식별 번호를 반홯나다.
콜백 함수의 인수로 2를 곱한 결괏값을 전달하면, 간단하게 비동기 작업의 결괏값을 반환값으로 사용할 수 있다.
function double(num, cb) {
setTimeout(() => {
const doubleNum = num * 2;
cb(doubleNum);
}, 1000);
}
double(10, (res) => {
console.log(res);
});
console.log("마지막");
// 마지막
// 20
함수 double
을 호출하며 두 번째 인수로 콜백 함수를 전달한다. 콜백 함수는 함수 double
의 매개변수 cb에 저장되며, 호출되면 인수로 전달한 값을 콘솔에 출력한다.
앞서 호출한 함수 double
이 비동기 작업이므로 해당 작업의 종료를 기다리지 않고 콘솔에 ‘마지막’이 출력된다.