웹 애플리케이션을 만들다 보면, 첫 번째 AJAX 요청의 결과를 받아서 두 번째 AJAX 요청을 해야 하는 상황이 자주 발생합니다.
예를 들어, “계산된 금액을 서버에서 받아오고(calculateAmounts), 그 결과를 토대로 실제 데이터를 저장(saveData)”하는 흐름이 있죠.
이때 AJAX 호출이 비동기적으로 실행되다 보니, 순서를 보장하지 않으면 타이밍 문제가 발생하여 잘못된 결과를 얻게 됩니다.
오늘은 콜백(callback) 기법을 활용하여 “첫 AJAX → 두 번째 AJAX”를 안전하게 순차 처리하는 방법을 가장 쉽게 설명해 보겠습니다.
1. 문제 상황
function saveData() {
//…
calculateAmounts(); // ① 금액 계산용 AJAX
collectAndSave(); // ② 계산 결과를 읽어서 저장용 데이터 준비
sendSaveAjax(); // ③ 저장용 AJAX
}
위와 같은 코드에서 calculateAmounts() 내부에 AJAX가 있다면,
- ① 계산 AJAX가 끝나기 전에
- ② collectAndSave() → ③ 저장 AJAX가 실행되어버립니다.
결과적으로 아직 계산이 완료되지 않은 시점에 잘못된 collectAndSave()가 실행되면서 오류가 발생하죠.
2. 콜백(callback)으로 순서 보장하기
콜백이란?
- 콜백 함수는 다른 함수에 인자로 넘겨져, 특정 시점(주로 성공·완료 시점)에 호출되는 함수입니다.
- “훗날 실행될 코드”를 미리 등록해두는 방식이죠.
순차 처리 흐름
- saveData() →
- calculateAmounts(done) 호출
- 계산 AJAX 성공 시 done() 실행
- collectAndSave() → 저장 AJAX
이렇게 콜백을 넘겨줌으로써 “계산 AJAX가 완전히 끝난 뒤”에야 후속 로직이 실행됩니다.
3. 실제 코드 예제
1) calculateAmounts 함수 수정
// calculateAmounts에 done 콜백 인자 추가
function calculateAmounts(done) {
const selectedType = $('input[name="radio_item"]:checked').val();
if (!selectedType) {
console.warn('타입 미선택');
return;
}
// (1) FormData 준비
const formData = new FormData();
formData.append('type', selectedType);
// … 기타 데이터 append …
// (2) 중복 호출 방지
if (ajaxRequest) ajaxRequest.abort();
// (3) 계산용 AJAX
ajaxRequest = $.ajax({
url: '/estimate/get_estimate_amount.php',
type: 'POST',
data: formData,
processData: false,
contentType: false,
dataType: 'json',
success(resp) {
if (!resp.success) {
console.error('계산 실패:', resp.error);
} else {
// 화면에 계산 결과 반영(예: 합계, 수량 업데이트)
$('#estimateTotal').val(resp.data.total.toLocaleString());
}
ajaxRequest = null;
// **계산이 끝난 뒤** 콜백 실행
if (typeof done === 'function') done();
},
error(xhr, status, err) {
console.error('AJAX 오류:', status, err);
ajaxRequest = null;
// 에러 시에도 콜백 호출 여부 결정 가능
if (typeof done === 'function') done();
}
});
}
2) saveData에서 콜백 넘기기
function saveData() {
// (A) 유효성 검사, 모드 결정 등 기존 로직…
showMsgModal('저장 중입니다…');
// calculateAmounts에 콜백 전달!
calculateAmounts(function() {
// ① 계산 완료 후 데이터 스냅샷 저장
collectAndSave();
// ② 라디오 버튼 값 세팅
const selectedRadio = $('input[name="radio_item"]:checked').val();
$('#major_category').val(selectedRadio);
// ③ 실제 저장 AJAX
const form = $('#board_form')[0];
const datasource = new FormData(form);
if (ajaxRequest_write) ajaxRequest_write.abort();
ajaxRequest_write = $.ajax({
url: 'insert.php',
type: 'POST',
data: datasource,
processData: false,
contentType: false,
dataType: 'json',
success(data) {
console.log('저장 성공:', data);
hideMsgModal();
// 필요한 후속 처리…
},
error(jqxhr, status, error) {
console.error('저장 오류:', status, error);
hideMsgModal();
}
});
});
}
// 버튼 바인딩
$('#saveBtn').click(saveData);
4. 장단점 및 확장
장점
- 순서 보장: 첫 AJAX가 끝난 뒤에만 다음 로직 실행
- 가독성: 비동기 흐름이 명확해짐
- 유연성: 콜백 대신 Promise, async/await로도 확장 가능
Promise 버전 (참고)
function calculateAmounts() {
return new Promise((resolve, reject) => {
// … AJAX 호출 …
success() { resolve(); }
error() { reject(); }
});
}
function saveData() {
calculateAmounts()
.then(() => {
collectAndSave();
return sendSaveAjax();
})
.then(data => console.log('완료', data))
.catch(err => console.error(err));
}
5. 마무리
- 콜백 함수를 잘 활용하면 복잡한 비동기 흐름도 순차 처리로 간단히 구현할 수 있습니다.
- 점차 익숙해지면, Promise나 async/await로 더 깔끔하게 정리할 수 있으니 단계별로 도전해 보세요.
이 글이 AJAX 순차 호출로 고민 중인 여러분께 도움이 되었기를 바랍니다!
반응형
'IT tech Coding > ajax' 카테고리의 다른 글
PHP + JavaScript로 반올림 오차 없는 동적 견적 계산 구현하기 (0) | 2025.06.27 |
---|---|
AJAX 요청 실패 시 디버깅: 구체적인 오류 정보를 알아내는 방법 (0) | 2024.12.02 |
ajax abort 지옥에서 탈출하기, 하루종일 삽질일기 (0) | 2023.04.18 |
ajax 누구냐 넌? 대단하다고 들었는데, 도대체 가.... (0) | 2019.07.09 |
ajax Can I use 사이트를 통해 fetch 호환성여부 확인가능 (0) | 2019.06.29 |