Callback 함수

전서희·2022년 5월 24일
0

JavaScript

목록 보기
2/3
post-thumbnail

callback 함수란?

  • 다른 함수의 인자로 전달되는 함수, 그 함수 자체를 콜백함수(callback function)라고 한다.
  • 매개변수로 넘겨진 함수는 넘겨 받고 이를 실행할 수 있도록 나중에 다시 불러야 하는데, 이 불러달라는 것에 착안하여 Call back이라는 이름이 붙었다.
function dessert(count, eat, good) {
		count < 3 ? eatDessert() : goodDessert();
}

function eatDessert() {
    console.log('오늘 먹어야 할 간식을 먹어주세요');
}

function goodDessert() {
    console.log('오늘 먹어야할 간식을 모두 먹었습니다');
}

dessert(4, eatDessert, goodDessert);

dessert 함수를 호출할 때 매개변수로 count에 숫자 값을, eat과 good에 각각 eatDessert 함수와 gooddessert 함수를 전달했다. 여기서 eatDessert와 goodDessert 함수가 콜백함수(나중에 다시 불러주는 함수, 함수의 인수로 들어간 함수)인 것이다.

동기/비동기 처리

Javascript 기본적으로 호이스팅이 된 이후에 순차적(동기적)으로 실행
순차적 처리하는 것이 아니라 다른 작업을 동시에 진행하고 싶으면 함수를 비동기 형태로 전환해주면 됨
그러기 위해서는 setTimeout 이라는 함수를 사용해주면 됨
setTimeout은 일정시간 후에 특정코드, 함수를 의도적으로 지연한 뒤 실행하고 싶을 때 사용하는 함수

호이스팅?

  • var 변수와 함수선언들이 제일 위로 올라가는 것

다음과 같은 코드에서 동기, 비동기가 무엇인지 살펴보자

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

실행 순서는 1 -> 3- > 2
두번째 줄은 비동기적으로 처리된다.
처리 순서는 동기 -> 비동기 순으로 실행된다.

callback 함수도 2가지의 경우로 정리할 수 있다.
1. synchronous callback(동기적 함수)
2. Asynchronous callback(비동기적 함수)

좀 더 긴 코드에서 동기, 비동기를 구분해보자

console.log('1');
setTimeout(function(){
    console.log('2');
},1000);

console.log('3');

//동기 콜백

function printImmediately(print){
    print();
}
printImmediately(()=>console.log('hello'));

//비동기 콜백
function printWithDelay(print, timeout){
    setTimeout(print, timeout);
}
printWithDelay(()=> console.log('async callback'),2000);

실행 순서는 다음과 같다. 왜 이런 결과가 나오게 되었을까?

//동기 콜백
function printImmediately(print){
    print();
}

//비동기 콜백
function printWithDelay(print, timeout){
    setTimeout(print, timeout);
}

console.log('1'); //동기 1
setTimeout(function(){console.log('2');},1000); //비동기 4
console.log('3'); //동기 2
printImmediately(()=>console.log('hello')); //동기 3 
printWithDelay(()=> console.log('async callback'),2000);//비동기 5
  • 함수 선언이 가장 위로 올라감!
  • 동기적으로 진행되다가 setTime 같은 함수가 있으면 비동기적으로 처리됨
  • 시간이 0.001초여도 무조건 동기부터 실행이 되고 비동기가 실행 됨!

정리

  1. 콜백은 나중에 다시 불러오는 함수

  2. 자바스크립트는 원래 동기적으로 실행됨

  3. 하지만 데이터를 빨리 받아오는 등 속도를 높이기 위해서 비동기적으로 바꿀 필요성이 있음

  4. 그럴 때 사용하는 것이 setTime 뒤에 몇초후에 받아올지 정해줌

  5. 동기 부터 먼저 진행

Callback 지옥

앞에서 배운 callback 함수를 여러번 중첩해서 사용한다면 Callback 지옥이라는 현상을 맛볼 수 있다. 지양해야 하는 방법이며 어떤 코드인지 살펴보고 어떤 점이 안좋은지 알아보자!

  1. 사용자에게 아이디와 패스워드를 입력받음
  2. 서버에게 로그인 해줘!
  3. 로그인한 사용자의 아이디를 받아와서 roles를 다시 요쳥해서 받아올 것
  4. 역할이 성공적으로 받아와 진다면 사용자의 object가 있겠죠~
class UserStorage{
    loginUser(id, password, onSuccess, onError){
        setTimeout(()=>{
            if(
                (id==='ellie' && password ==='dream')||
                (id==='coder'&& password === 'academy')
            ){
                onSuccess(id);//id,password 일치하면 onSuccess함수에 id 인자 넘겨주기
            }else{
                onError(new Error('not found')); //일치하지 않으면 실패
            }
        },2000);
    }
    getRoles(user, onSuccess, onError){
        setTimeout(()=>{
            if(user === 'ellie'){
                onSuccess({name: 'ellie', role: 'admin'}); //user가 ellie라면 onSuccess함수 이름엔ellie, 역할엔 admin 넘겨주기
            }else{
                onError(new Error('no access')); //아니면 no access error 반환하기
            }
        },1000);
    }
}

const userStorage = new UserStorage();
const id = prompt('enter your id');//id값 입력받기
const password = prompt('enter your password');//비밀번호 값 입력받기

userStorage.loginUser(
    id, 
    password, 
    user=>{
        userStorage.getRoles(
            user, 
            userWithRole => {
                alert(`hello ${userWithRole.name}, you have a ${userWithRole.role} role`); //name값과 role 값 가져와서 알려주기 
            },
            error => {
                console.log(error); //에러반환하기
            }
            );
    },
    error=>{console.log(error)})

callback지옥의 단점

  1. 가독성이 안좋다, 비즈니스 로직을 한눈에 이해하는 것이 어려움
  2. 에러가 발생하거나 디버깅을 해야하는 경우에도 에러 파악하기 어려움
  3. 유지보수가 어려움
profile
UX디자인을 배우다 코딩의 매력에 흠뻑빠져 프론트엔드 개발자가 되고자 하는 코린이

0개의 댓글