콜백 함수는 다른 함수의 인자로 전달되는 함수이다.

콜백 함수를 전달 받는 함수는 전달 받은 콜백을 함수 내부에서 필요할 때 호출하도록 구현되어 있음.
콜백 함수 자체가 비동기와 관련이 있는 것은 아님.
하지만 비동기를 배울 때, 콜백 함수를 접하는 이유는 비동기 처리를 할 때 콜백 함수가 유용하게 사용되기 때문.
그래서 비동기 처리에 사용되는 콜백 함수를 '비동기 콜백'이라고 부른다. 비동기적으로 수행되는 작업은 정확히 언제 끝나는지 알기 힘듦. + 코드의 실행순서가 뒤죽박죽이 되기도 함. 만약 특정 비동기 작업이 끝나고 나서 후처리를 해줘야 한다면? 예를 들어 네트워크 통신 같은 비동기 작업이 완료되고 나서 후처리로 받아온 데이터를 처리하는 코드가 실행되도록 해야 한다면 어떻게 하면 될까? '콜백 함수'를 사용하면 됨! 이것이 '비동기 콜백'.
'getData'라는 함수를 만들었음. 이 함수는 서버에서 데이터를 받아오는 비동기 작업을 함. 2초가 걸린다는 가정, setTimeout을 사용해서 네트워크 통신에 걸리는 시간을 흉내내봄. 함수를 호출하면 콘솔이 실행될 것임.


2초 뒤에 출력됨!
이제 내가 해야할 일이 있음. getData 함수가 서버로부터 데이터를 받아오는 작업을 완료하면, 그에 대한 후처리를 해줘야 한다. 어떻게 해야 할까?

이런 식으로 코드를 짜면, 비동기 작업이 끝나기도 전에 
이렇게 먼저 출력이 되기 때문에 x.
내가 원하는 것은 getData 함수가 끝난 다음에 후처리를 하는 코드를 호출하는 것. 여기서 '비동기 콜백'이 등장. 콜백 함수를 사용하면 가능함. 일단, getData 함수가 매개변수로 콜백 함수를 받게끔 만든다. 이후 서버에서 데이터를 받아오는 작업이 끝나면, 전달해준 콜백 함수를 호출시켜줌.

이제 후처리를 하는 코드를 getData 함수의 인자로 전달해줄 것임.


실행시키면, 서버에서 데이터를 받아오길 기다렸다가 데이터를 받아온 후 바로 다음에 후처리를 하는 코드를 실행시킴. 내가 전달해준 콜백 함수가 callback이라는 변수에 들어가서 네트워크 통신이 완료된 다음에 호출이 되는 것임.

콜백 함수의 인자로 받아온 데이터를 넣을 수도 있음. 오브젝트를 하나 넣어봄. 콜백 함수가 매개 변수를 받게끔 만들어 놓고, console에는 받은 데이터의 이름... 이런 식으로 출력하게 만들 수도 있음.
이처럼 콜백 함수를 사용하면 비동기 작업이 완료된 후에 실행되어야 하는 코드를 명확하게 정의할 수 있다.
이번엔 온라인 쇼핑 시나리오를 만들어보자. 비동기 콜백이 야기할 수 있는 '콜백지옥'에 대해서... 
이렇게 세 가지 작업을 하는 함수를 만들 것임. 3가지 함수가 필요할 것이며 모두 비동기적으로 동작할 것임. 왜냐하면 3가지 함수 모두 네트워크 통신이 필요하므로 동기적으로 작동한다면 매우 비효율적. + 각 작업이 이전 작업에 의존한다는 조건을 붙여보자. 로그인 후, 장바구니에 넣고 결제가 실행되는 루트.


1초 뒤 실행됨.


1초 뒤에 출력됨.


카드번호는 소중하니까 slice 함수로 잘라서 6자리만 보이게 함.
이 세 작업들을 비동기적으로 실행하려면 어떻게 하면 될까?

login 함수를 호출해준다. 이제 로그인 작업이 완료되고 나서 장바구니에 넣는 작업을 수행해야 함. 로그인 함수에 전달해준 콜백 함수는 로그인이 실행되고 나서 수행되는 작업임. 

잘 출력됨. 근데 코드가 조금 복잡해지는 느낌이 듦. 콜백 함수의 중첩이 계속 되면, 코드의 가독성은 점점 떨어져서 유지보수가 힘듦. -> 콜백 지옥. 반드시 피해야 함.
↓
자바스크립트에서 제공하는 'Promise'를 사용하면 해결! 이는 2015년 ES6버전에서 등장한 문법임. 그전까지 콜백 지옥으로 고통받던 개발자들을 구원.