티스토리 뷰

우선 콜백함수에 앞서 동기식, 비동기식이 무엇인지 이해할 필요가 있습니다.

동기식이란, 먼저 시작된 하나의 작업이 끝날 때까지 기다렸다가 다 끝나면 다음 작업을 시작하는 방식입니다.

비동기식이란, 동기식과는 반대로 먼저 시작된 작업이 끝나지 않더라도 새로운 작업을 시작하는 방식입니다.

이렇게 되면 의도한 순서대로 작업이 진행되지 않아 마지막에 진행되어야 할 작업이 먼저 끝나거나 하는 문제가 생기겠죠?🧐

 

자바스크립트는 기본적으로 동기적으로 움직이는 언어입니다. 호이스팅 후에 제일 위에서부터 밑으로 실행합니다.

(*호이스팅이란? 함수선언, var이 제일 위로 올라감)

console.log(1);
console.log(2);
console.log(3);

//1
//2
//3

이렇게 순서대로 콘솔에 1, 2, 3이 출력되죠. 이것이 동기식입니다. 하지만 코드를 이렇게 작성하면 무슨 일이 벌어질까요?

console.log(1); //동기
console.log(2); //동기
setTimeout(()=>console.log('메롱'),2000); //비동기
console.log(3); //동기

//1
//2
//3
//메롱

네, 순서대로 실행되는 것이 아니라 1, 2, 3, 메롱이 출력되는데 그 이유는 setTimeout() 함수가 대표적인 비동기적 함수이기 때문이죠. 그래서 console.log('메롱')이 완료되기도 전에 console.log(3)이 실행되었습니다. 이것이 바로 비동기 방식입니다!

 

그렇다면 콜백함수를 사용하면 결과값이 어떻게 달라질까요?

function call(ftn){
    console.log(1);
    console.log(2);
    setTimeout(()=>{
        console.log('메롱');
        ftn();
    },2000);
}
call(()=>console.log(3));

//1
//2
//메롱
//3

네, 의도한 순서대로 잘 실행되었네요😊

콜백함수란 함수의 파라미터로 들어가는 함수를 가리킵니다. 우리는 콜백함수가 무엇인지도 모른 채 사실 많이 사용하고 있습니다.

<script>
    document.querySelector('.btn').addEventLisnter('click',function(){})
</script>

addEventLisnter 함수에 파라미터로 무엇이 들어가나요? 함수이죠! 이게 바로 콜백함수입니다.

<script>
    setTimeout(function(){},1000);
</script>

 

setTimeout 함수에도 파라미터로 함수가 들어갑니다. 1초 뒤에 이 함수를 실행해달라는 코드이죠.

<script>
    //방법1 - 익명함수
    document.querySelector('.btn').addEventLisnter('click',function(){
    	console.log(1);
    })
    
    setTimeout(function(){
    	console.log(1);
    },1000);
    
    //방법2 - 함수를 따로 만들기
    function ftn(){
    	console.log(1);
    }
    
    document.querySelector('.btn').addEventLisnter('click',ftn);
    setTimeout(ftn,1000);
    
    //방법3 - arrow function (ES6)
    document.querySelector('.btn').addEventLisnter('click',()=>{console.log(1)});
    setTimeout(()=>{console.log(1)},1000);
</script>

우리에게 익숙한 이 모든 코드들이 사실 콜백함수였습니다!

콜백함수는 동기식과 비동기식으로 나누어 사용할 수 있습니다.

//동기식
function call(ftn){
	console.log('내가 제일 먼저 출력')
	ftn();
}
call(()=>console.log('동기식 콜백'));

//비동기식
function back(ftn){
	setTimeout(ftn,2000);
}
back(()=>console.log('비동기식 콜백'));

그렇다면 콜백함수는 언제 쓰는 것일까요? 함수를 순차적으로 실행시키기 위해 쓰는 것입니다.

//콜백함수를 쓰지 않았을 때 비동기 방식의 문제점
function user(id){
    let info;
    setTimeout(()=>{
        info = {
            id: id,
            name: 'olly'
        };
    },1000);
    return info;
}
console.log(user(20)); //undefined
//setTimeout 함수의 실행이 완료되기도 전에 info를 return 시켰기 때문에 undefind

//콜백함수로 해결
function user(id,callback){
    let info;
    setTimeout(()=>{
        info = {
            id: id,
            name: 'olly'
        };
        callback(info);
    },1000);
}
user(20,(info)=>{
    console.log(info); //{id:20, name:'olly'}
});

하지만 콜백함수를 반복적으로 사용하다보면 콜백지옥이라 불리는 것을 경험할지 모릅니다.

ES6 문법에는 Promise라는 기능이 추가되었는데요, 다음 포스팅에서 프로미스에 대해 알아봅시다💕