[JavaScript] 콜백 함수를 통한 비동기 처리

parkheeddong·2023년 5월 8일

JavaScript

목록 보기
24/26
post-thumbnail

👀 콜백 함수란

나중에 호출되는 함수이다.

변수로 정의된 함수가 다른 함수에 전달되어서, 다른 함수 내에서 호출되는 것이다. 즉, 바로 실행되지 않고 다른 함수 내부에서 나중에 실행된다.

<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"}

✅ 위 두 케이스의 차이점?!

findUser() 함수는 결과값을 리턴하고 함수 외부에서 결과값을 이용하여 작업을 수행한다.

findUserAndCallBack() 함수는 결과값을 이용해 해야할 작업까지 함수 내부에서 수행해주기 때문에 결과값을 굳이 리턴할 필요가 없다.




1. 비동기함수와 동기함수

비동기 함수

호출부에서 실행 결과를 가다리지 않아도 되는 함수

동기 함수

호출부에서 실행 결과가 리턴될 때 까지 기다려야 하는 함수

브라우저에서 로직이 동기 함수만으로 실행될 경우, 기다리는 시간이 많아져서 사용자 경험에 부정적인 영향을 미칠 것이다.

비동기 함수의 가다리지 않아도 되는 이점 때문에, 비동기 함수는 자바스크립트처럼 싱글 쓰레드 환경에서 실행되는 언어에서 광범위하게 사용된다.

더불어 로직을 순차적으로 처리할 필요가 없기 때문에 동시 처리에서도 유리하다.

BUT ❗ 코딩을 하는 개발자 입장에서는 비동기 함수는 동기 함수에 비해서 좀 덜 직관적으로 느껴진다. 동기 함수처럼 순차적 처리가 보장되지 않기 때문이다.




2. 비동기함수의 문제점

setTimeout()

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()과 같은 비동기 함수를 호출하게 되면, 함수의 실행이 완료도 되기 전에 다음 라인이 실행되어 버리기 때문에 각별히 주의를 해야 한다.




3. 콜백함수를 이용한 비동기처리

해결방법 ?! 콜백 함수를 이용해서 해결할 수 있다!

함수로 부터 결과값을 리턴 받기를 포기하고, 결과값을 이용해서 처리할 로직을 콜백 함수에 담아 인자로 던진다.

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"}




4. 콜백함수를 이용한 비동기처리의 한계

자바스크립트 프로젝트가 점점 더 복잡해지면서 최근에는 콜백 함수를 인자로 넘겨서 비동기 처리를 하는 스타일을 피하는 추세다.

왜냐하면 콜백 함수를 중첩해서 사용하게 되면 계속해서 코드를 들여쓰기 해야하고 그러다보면 코드 가독성이 현저하게 떨어지게 되기 때문.

결국, 많은 개발자들이 콜백 지옥이라고 불리는 끔찍한 상황을 겪게 되었고 최근에는 Promise나 async/await를 이용하는 방법들로 대체되고 있다.




출처 :https://www.daleseo.com/js-async-callback/

0개의 댓글