Callback ?

MyeonghoonNam·2021년 2월 9일
0

JavaScript의 동기적, 비동기적 처리에 대해 이해하자

동기와 비동기 ?

  • 동기(Syncronous) : 하나의 요청에 의한 응답이 완료 된 후에 다음 요청을 처리하는 방식.

  • 비동기(Asynchronous) : 하나의 요청을 보낸 후 응답에 관계없이 다음 요청을 처리하는 방식.


JavaScript는 동기적 언어인가 ?

JavaScript는 Single Thread를 사용하기에 동시에 두 가지 작업을 할 수 없는 동기적 언어이다. 그렇기에 호이스팅(hoisting) 후 작성된 코드의 순서대로 동작이 이루어진다.

호이스팅 ?

  • JavaScript의 함수는 실행되기 전에 함수 안에 필요한 변수값들을 모아서 해당 함수 유효 범위의 최상단에 선언하는 것.

  • 호이스팅의 대상은 var 변수 선언과, 함수 선언문만 해당된다.
    선언만 위로 끌어 올려지며, 할당은 끌어 올려지지 않는다.
    let/const 변수 선언과 함수표현식에서는 호이스팅이 발생하지 않는다.
// 함수선언문
function test(){
	console.log('test');
}
// 함수표현식
let example = function(){
	console.log('test');
}

그러나 JavaScript는 동기적 언어이지만 비동기식의 동작을 조작할 수 있다. 대표적으로 Callback 함수가 있다.


Callback 함수

  • 다른 함수의 매개변수로 사용되거나 이벤트에 의해 호출되어지는 함수를 말한다.

  • 비동기적으로 작성된 함수들을 사용자의 편의에 따른 순서로 동기적 처리가 가능하게 해준다.

function foo(a, b, callback)
{
    console.log("i'm foo(), a:%s, b:%s", a, b);
    callback('success call foo()');
}

foo(1, 2, function(msg){
    console.log(msg);
});

foo() 함수에 함수 객체가 매개변수로 사용되어 지는 상태. 처리 순서를 보면 foo 가 실행되고 마지막에 callback 을 부른다. 이는 마치 일반적인 프로그래밍에서 return 을 하는 것과 유사하게 foo() 함수의 세번째 인자인 function(msg) { } 로 이어진다. 여기서 사용된 callback 이라는 단어는 노드나 자바스크립트에서 특수하게 사용되는 예약어(reserved word)가 아님을 명심하자. 동작을 가장 잘 표현하고 있기 때문에 범용적으로 사용되고 있는 단어이다.

그러나 비동기처리를 위하여 callback 함수를 너무 많이 중첩하여 사용하면 코드의 가독성이 크게 떨어지고 함수끼리 꼬이는 상황이 발생한다면 에러가 발생할 확률이 커지게 된다. 이러한 경우를 콜백지옥이라고 부르며 아래와 같은 예제를 보면 이해가 될 것이다.

class UserStorage {
  loginUser(id, password, onSuccess, onError) {
    setTimeout(() => {
      if (
        id === 'hoon' && password === '0822'
      ) {
        onSuccess(id);
      } else {
        onError(new Error('not found'));
      }
    }, 2000);
  }

  getRoles(user, onSuccess, onError){
    setTimeout(() => {
      if (user === 'hoon') {
        onSuccess({name:'hoon', role:'admin'});
      } else {
        onError(new Error('not found'));
      }
    }, 1000);
  }
}

const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your pw');

userStorage.loginUser(
  id,
  password,
  user => {
    userStorage.getRoles(
      user,
      userWithRole => {
        alert(`Hello ${userWithRole.name}, you have a ${userWithRole.role}`);
      },
      error => {
        console.log(error);
      }
    )
  },
  error => {
    console.log(error);
  }
)

그렇다면 비동기 처리를 위한 Callback의 해결책은 무엇일까?? 바로 Promise 함수가 해결책으로 활용되고 있다. 그렇다면 다음 포스팅에서는 Promise 함수에 대해서 알아보자.

profile
꾸준히 성장하는 개발자를 목표로 합니다.

0개의 댓글