지난 시간은 주문 API를 구현하는 중이었어요. 하나의 주문을 처리하기 위해 여러 개의 쿼리가 순서대로 안전하게 동작해야하기 때문에, 비동기 처리 개념을 먼저 정리할게요.
동기(Synchronous)와 비동기(Asynchronous)는 요청한 작업이 끝날 때까지 기다릴지 말지를 결정하는 방식이에요.
비동기 사용 시 주의할 점
비동기를 사용할 때는 앞선 요청의 결과가 다음 작업에 영향을 미치는지 꼭 확인해야 해요.
예를 들어 숫자 2 를 받아 2배 곱해주는 함수 를 거친 뒤, 그 결과에 1을 더해주는 함수 를 실행한다고 가정해 볼게요.
동기로 처리하면 정상적으로 (2 * 2) + 1 = 5 가 나오겠지만, 비동기로 처리해버리면 곱하기가 끝나기도 전에 더하기가 먼저 실행되어서 2 + 1 = 3 이라는 결과가 나올 수 있어요!
비동기 작업들의 순서를 우리가 원하는 대로 제어하기 위한 방법에는 크게 3가지가 있어요.
.then() 으로, 에러가 발생했을 때는 .catch() 로 결과를 깔끔하게 처리할 수 있어요.await 는 반드시 async 키워드가 붙은 함수 내부에서만 사용할 수 있어요!비동기 처리를 쉽게 이해하기 위해 setTimeout() 을 사용해 2초 뒤에 값을 반환하도록 임의로 코드를 작성해 봤어요.
아래 세 가지 방법 모두 결과적으로 200 을 안전하게 출력해요.
// 1. Callback 방식
const testCallback = (callback) => {
setTimeout(() => {
const value = 100;
callback(value);
}, 2000);
};
testCallback((num) => {
let data = num * 2;
console.log(data); // 200
});
// 2. Promise 방식
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const value = 100;
resolve(value); // 정상 처리 시 resolve로 값을 넘겨줌
}, 2000);
});
promise
.then((result) => {
let data = result * 2;
console.log(data); // 200
})
.catch((error) => {
console.log(error);
});
// 3. async & await 방식 (가장 권장!)
const testAsync = async () => {
let data = await promise; // promise가 완료될 때까지 기다림
data *= 2;
console.log(data); // 200
}
testAsync();
공부하다 보니 '여러 쿼리문을 순서대로 처리할 때 비동기 문법을 사용하는 방법만 있는 걸까?' 하는 의문이 들었어요.
찾아보니 무조건 비동기 제어만 정답은 아니었어요. DB 드라이버(Node.js의 mysql 모듈 등) 설정에서 다중 쿼리(Multiple Statements) 옵션을 켜서 파라미터를 매핑해 한 번에 처리하는 방법도 존재한다고 해요.
mysql 다중쿼리 블로그