
나중에 호출되는 함수이다.
변수로 정의된 함수가
다른 함수에 전달되어서, 다른 함수 내에서 호출되는 것이다. 즉, 바로 실행되지 않고 다른 함수 내부에서 나중에 실행된다.<button onclick="onClick">버튼</button> <script> function onClick(){ alert("버튼을 누르셨습니다"); } </script> // 버튼을 클릭하면 이벤트 핸들러가 콜백함수 onClick을 호출한다.즉, 특정 함수에 전달되어서 어떤 조건에 의해 호출되는 함수를 '콜백함수'라고 한다..!
두가지 함수의 형태를 생각해 보자 !
function findUser(id) {
const user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
return user;
}
const user = findUser(1);
console.log("user:", user);
결과 : user: {id: 1, name: "User1", email: "1@test.com"}
function findUserAndCallBack(id, cb) {
const user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
cb(user);
}
findUserAndCallBack(1, function (user) {
console.log("user:", user);
});
결과 : user: {id: 1, name: "User1", email: "1@test.com"}
비동기 함수
호출부에서 실행 결과를 가다리지 않아도 되는 함수
동기 함수
호출부에서 실행 결과가 리턴될 때 까지 기다려야 하는 함수
비동기 함수의 가다리지 않아도 되는 이점 때문에, 비동기 함수는 자바스크립트처럼 싱글 쓰레드 환경에서 실행되는 언어에서 광범위하게 사용된다.
더불어 로직을 순차적으로 처리할 필요가 없기 때문에 동시 처리에서도 유리하다.
BUT ❗ 코딩을 하는 개발자 입장에서는 비동기 함수는 동기 함수에 비해서 좀 덜 직관적으로 느껴진다. 동기 함수처럼 순차적 처리가 보장되지 않기 때문이다.
function findUser(id) {
let user;
setTimeout(function () {
console.log("waited 0.1 sec.");
user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
}, 100);
return user;
}
const user = findUser(1);
console.log("user:", user);
user: undefined
waited 0.1 sec.
setTimeout()은 비동기 함수의 호출이기 때문에 실행이 완료될 때 까지 기다리지 않고 다음 라인인 11번째 줄로 넘어간다.
따라서 14번째 줄의 findUser(1)는 undefined를 리턴하게 되고 user 변수에는 그대로 undefined가 할당된다.
0.1초 후에 setTimeout() 함수의 첫번째 인자로 넘어간 콜백 함수가 실행되면서 waited 0.1 sec.가 출력되고 user 로컬 변수에 원하는 객체가 할당되었지만 이미 때 늦은 상황이 되었다.
이와 같이 setTimeout()과 같은 비동기 함수를 호출하게 되면, 함수의 실행이 완료도 되기 전에 다음 라인이 실행되어 버리기 때문에 각별히 주의를 해야 한다.
function findUserAndCallBack(id, cb) {
setTimeout(function () {
console.log("waited 0.1 sec.");
const user = {
id: id,
name: "User" + id,
email: id + "@test.com",
};
cb(user);
}, 100);
}
findUserAndCallBack(1, function (user) {
console.log("user:", user);
});
waited 0.1 sec.
user: {id: 1, name: "User1", email: "1@test.com"}
자바스크립트 프로젝트가 점점 더 복잡해지면서 최근에는 콜백 함수를 인자로 넘겨서 비동기 처리를 하는 스타일을 피하는 추세다.
왜냐하면 콜백 함수를 중첩해서 사용하게 되면 계속해서 코드를 들여쓰기 해야하고 그러다보면 코드 가독성이 현저하게 떨어지게 되기 때문.
결국, 많은 개발자들이 콜백 지옥이라고 불리는 끔찍한 상황을 겪게 되었고 최근에는 Promise나 async/await를 이용하는 방법들로 대체되고 있다.