본문으로 건너뛰기

콜백 후벼파기

콜백 후벼파기

콜백함수에 대해서 잘 알고 적절히 사용하기 위해서는 완벽한 이해가 필요하다.

ajax에서는 당현히 나오고,

경우에 따라서는 '왜 이게 먼저실행되지?' 라는 상황에서

실행순서를 원하는데로 움직이게 수정해야 할 상황도 온다.

일단 다음 코드를 보자

console.log("start");

setTimeout(function () {
console.log("Hello Callback");
}, 1000);

console.log("end");

결과는

start
end
Hello Callback

자바스크립트가 setTimeout부분을 콜스택에 쌓아놓고

바로 console.log("end")를 실행시켰기 때문에 이렇게 된다.

이걸. 원하는 순서대로. start → Hello Callback → end 로 하려면

setTimeout내부에서 end를 출력하는 함수를 호출 하는 식으로 하면 된다.

console.log("start");

setTimeout(function () {
console.log("Hello Callback");
callbackFunc();
}, 1000);

function callbackFunc() {
console.log("end");
}
start
Hello Callback
end

위의 코드같이 함수 내부에서 함수를 호출한다. 정도만 파악하고

다음 코드를 보자.

function printData() {
setTimeout(function () {
let sumData = 1 + 2;
console.log(sumData);
}, 1000);
};

printData();
console.log('end');
end
3

1+2의 합을 먼저 찍고 end를 찍고싶은데 end가 먼저 나왔다.

3이 찍히고 end가 찍히도록 바꿔보자.

function printData(callback) {
setTimeout(function () {
let sumData = 1 + 2;
console.log(sumData);
callback();
}, 1000);
};

printData(function() {console.log('end');});
3
end

자바스크립트의 특징 : 함수를 인자로 넘길수가 있다.

callbackFunc( 인자로 함수 );

를 사용하면된다.

printData를 호출할때 인자로 함수를 넘겨준다. 그것이 콜백함수다.

printData(function() {console.log('end');});  // <-- 이렇게 써도 되는데 
printData(function() {   // 가독성을 위해서 이렇게 줄바꿈해서 쓸 뿐이다
console.log('end'); // printData() 의 괄호안에 function(){console.log('end);}
}); // 똑같이 있다는것을 알 수 있다.

실행되어지는 함수에서

function printData(콜백함수) ← 이렇게 받아주고

받았으니~ 받은 함수를 호출. callback();

-_-;; 별거 없다.

콜백 함수 : 함수를 인자로 넘긴것 = 인자로써 함수를 넘긴것 = 인자를 함수로 받은것

관례인데 밑에처럼 callback함수 인자는 보통 함수에서 마지막 인자로 많이 쓴다.

물론 꼭 그러라는 법은 없어서 경우에 따라서 중간에 쓰는 사람도 있다 -_-;;;

function helloWorld(hello, world, callback) {
hello 이용
world 이용
콜백함수 호출
}

ajax로 보게되면

function ajaxFunc(dataOne, dataTwo) {

dataThree = dataOne / dataTwo;
dataFour = dataOne + dataTwo;

params = {
dataThree : dataThree,
dataFour : dataFour
};

$.ajax({
url: url,
type: 'POST',
data: params,
success: function(data) {
result = data;
}
})
return result;
}

이런 느낌인데. success부분이 콜백이 된다.

function ajaxFunc(dataOne, dataTwo) {

dataThree = dataOne / dataTwo;
dataFour = dataOne + dataTwo;

params = {
dataThree : dataThree,
dataFour : dataFour
};

$.ajax({
url: url,
type: 'POST',
data: params,
success: function(data) {
result = data;
},
error: function(jqXHR, texStatus, errorThrown) {

}
})
return result;
}

이런 코드라면

success를 콜백이라 부르고, error부분을 에러 콜백이라고 부르기도 한다.

ajaxFunc(data1, data2, callback, errCallback) 이런식으로 쓰기도 한다.


async await스타일로 쓰고 싶을때

(promise패턴은 promise then 지옥이 되기도 하므로 개인적으로는 async await패턴을 좋아한다)

이전 코드를 async await스타일로 쓰고 싶다면

async function doAjax(dataOne, dataTwo) {
dataThree = dataOne / dataTwo;
dataFour = dataOne + dataTwo;

params = {
dataThree: dataThree,
dataFour: dataFour,
};
const result = await $.ajax({
url: url,
type: "POST",
data: params,
});

return result;
}

이런식이 된다.

함수앞에 async를 붙히고, const result 에 await한 ajax를 담는다 라고 생각하면 된다.

이 코드에서 에러 처리 부분까지 넣게되면 이렇게 된다.

async function doAjax(dataOne, dataTwo) {
dataThree = dataOne / dataTwo;
dataFour = dataOne + dataTwo;

params = {
dataThree: dataThree,
dataFour: dataFour,
};

try {
result = await $.ajax({
url: url,
type: "POST",
data: params,
});
return result;
} catch (error) {
console.error(error);
}
}

콜백 헬과 조우 했을때

어찌어찌하다 그냥 쭉쭉 작성하던 코드가 콜백헬이 되는 경우가 있다.

이렇게 말이다....

$.ajax {

success: function() {
$.ajax {

success: function() {
$.ajax {
}
}
}
}

}

그런경우에..

파해법1

일단. 코드를 쓸때.

이벤트 핸들러용 코드를 따로 빼고(첫 이벤트 진입 함수),

그 안에서 개별 ajax를 관리하는 식으로 적는것이 포인트

파해법2

그리고 두번째로 이것을 해결하기위해

프로미스 방식이나 async방식을 써야한다.

개인적으로는 async방식이 보기 편하고 잘 읽혀서 async방식을 선호한다.

이 방식은 프로미스에서 파생되었기 때문에 프로미스를 기본적으로 잘 이해하고 있어야 한다. 고는 한다 -_-;;

물론 잘 모른다고 아예 못쓰는건 아니다.

코드로 보자

async function callAjax(firstNum, secondNum) {
let num1 = firstNum;
let num2 = secondNum;

const result = await $.ajax({
// url: 'http://127.0.0.1:8080/ajax',
type: "GET",
data: { num1: num1, num2: num2 },
});
return result;
}
async function onclickAjax(firstNum, secondNum) { // 이벤트가 시작되는 진입점
const result = await callAjax(firstNum, secondNum); // 네스트 되는 ajax
if (result == 0) {
// 처리
} else {
// 처리
}
}

onclickAjax라는 이벤트 핸들러용 펑션에서 인자 두개를 넘겨받고

calAjax라는 펑션에게 파라미터를 두개 넘겨주면서 실행한다. 그 결과를 const result에 담는다

result의 결과값에 따라서 조건분기를 한다.

result 분기 부분에서 또 ajax처리의 await async를 넣을수도 있다.

포인트는. function앞에 async써주고 콜백으로 실행할 펑션에 await를 써주는것.

마찬가지로.

이벤트 핸들러에서 불려지는

  • 개별 펑션에도 async를 붙인다
  • 개별펑션의 ajax실행부분또한 const result = await $.ajax 이런식으로 적는다.