개발을 하다보면 API를 호출 함수에 항상 붙는 async/await 키워드는 어떻게 비동기 처리를 하는 것인지에 대한 궁금증이 생겼다. 그래서 이번 글에서는 그 동안 모호하게만 알고 있던 개념인 비동기 처리에 대한 내용을 정리해보고자 한다.
그렇다면, 비동기 처리를 왜 사용하는지에 대해 알아보자. 먼저 자바스크립트에서 비동기 처리를 사용해야하는 이유를 알기 위해서는 동작 원리에 대해 알아야 한다.
자바스크립트는 Java, Python 등의 언어와는 다르게 멀티 스레드를 지원하지 않는 싱글 스레드 언어이다.
- 멀티 스레드는 하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행하는 것을 의미합니다.
- 싱글 스레드는 하나의 프로세스 내에서 단 하나의 작업 흐름(스레드)만을 갖는것을 말한다.
- 스레드는 프로세스 내부의 실행 단위를 말한다.
- 프로세스는 실행중인 프로그램이다.
* 동기(Synchronous)실행
특정 작업이 완료될 때까지 대기하며, 해당 작업이 완료되기 전에는 다음 작업으로 넘어가지 않는 실행 방식이다.
장점: 작업의 순서와 실행 시간을 예측할 수 있기 때문에 결과의 일관성을 유지하기가 쉽다.
단점: 프로그램의 실행 중 블로킹(작업중단)이 발생한다.
* 비동기(Asynchrnous)실행
특정 작업이 완료되지 않아도 다른 작업을 병렬적으로 실행할 수 있는 방식이다.
장점: 프로그램의 실행 중 블로킹(작업중단)이 발생하지 않아, 다른 작업을 계속 실행할 수 있다.
단점: 작업의 결과가 즉시 반환되지 않을 수 있어 작업의 순서와 실행 시간을 예측하기 어렵다.
그러므로 각 작업의 특성에 맞게 동기와 비동기를 적절하게 사용하는 것이 중요하다!
- 타이머 함수로, Web API이다.
- 첫 번째 인자: 타이머가 종료된 후 실행할 콜백 함수
- 두 번째 인자: 타이머에 지정할 시간(밀리초 단위)
setTimeout(function(){ console.log("Hello World"); }, 2000); console.log("setTimeout() example...");
위 코드는 콘솔에 "setTimeout() example..."를 먼저 출력하고, 2초가 지난 다음 "Hello World"을 출력합니다.
그렇다면 비동기 실행을 사용하면서 함수의 실행 순서를 보장할 수 있는 방법은 없을까? 자바스크립트에는 이를 해결하기 위한 3가지 방법이 존재하는데 하나씩 살펴보도록 하자.
첫 번째 방법은 바로 콜백 함수이다. 나중에 실행돼야할 함수를 콜백 함수로 넘겨주는 방식이다.
const printRabbit = (callback) => {
setTimeout(() => {
console.log("🐰");
callback();
}, 3000);
};
const printDog = () => { console.log("🐶"); };
printRabbit(printDog);
위 예시처럼 구현하면 setTimeout() 함수는 비동기로 실행되면서 3초 뒤에 토끼와 강아지가 차례대로 출력되도록 할 수 있다.
비동기 처리를 위해 만들어진 객체이다.
아래 코드는 앞에서 살펴봤던 예제를 async/await 키워드를 이용해 다시 작성한 것이다.
const printRabbit = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log("🐰");
resolve();
}, 3000);
});
};
const printDog = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log("🐶");
resolve();
}, 3000);
});
};
const printCat = () => {
console.log("🐱");
};
const printAnimals = async () => {
await printRabbit();
await printDog();
printCat();
};
printAnimals();