[JS] Callback개념 / 콜백지옥 > Promise

HYEJIN·2022년 7월 18일
0

자바스크립트

목록 보기
6/10

콜백 함수

  1. 다른 함수의 인자로써 이용되는 함수 ( = 다른함수의 매개변수로 함수를 전달하는 방식 )
  2. 어떤 이벤트에 의해 호출되어지는 함수.
function addCallback() {
    setTimeout(() => {
      let sum = 1 + 1;
      console.log(sum); 
    }, 2000); //2초뒤에 이코드가 실행
  }

  addCallback();
  console.log("end");

<예상 출력결과>
2
end
출력될 것 같지만 아니다.

<정답 출력결과>
end
2

end가 먼저 출력되는 이유는?

자바스크립트는 동기적이지만 setTimeout()과 같이 비동기로 처리되는 것에 영향을 받게되면 실행순서가 밀리게 된다. ( 자바스크립트 동작원리 참고 / 추후 작성예정 )

비동기란? 언제 코드가 실행될 지 예측할 수 없는것이다.
콜백함수는 비동기 방식의 문제로 등장했다고 하니, 당연히 비동기의 반대가 된다.
콜백함수는 "코드의 실행을 기다려주기 위해 존재하는 함수"이다.

function addCallback(fn) {
    setTimeout(() => {
      let sum = 1 + 1;
      console.log(sum);
      fn();
    }, 2000); //2초뒤에 이코드가 실행
  }

  addCallback(function () {
    console.log("end");
  });

<출력>
2
end


🤯콜백지옥,,

만약 계속해서 콜백 콜백 콜백을 부르게 된다면,,,,, 지옥을 맛볼것이다!!!

아래 코드의 경우 큰 틀로 보자면,

1) prompt로 사용자 id 와 password를 입력받는다.

2) 아이디와 비밀번호가 매칭된다면, getRole 함수를 호출하여 해당 계정의 역할을 alert 창으로 보여준다.

>> 이것을 callback 함수를 활용

//Callback Hell example

class UserStorage {
  loginUser(id, password, onSuccess, onError) {
    setTimeout(() => {
      if (
        (id === "hyejin" && password === "dream") ||
        (id === "corder" && password === "academy")
      ) {
        onSuccess(id);
      } else {
        onError(new Error("not found"));
      }
    }, 2000);
  }
  getRoles(user, onSuccess, onError) {
    setTimeout(() => {
      if (user === "hyejin") {
        onSuccess({ name: "hyejin", role: "admin" });
      } else {
        onError(new Error("no access"));
      }
    }, 1000);
  }
}

//id와 password를 Prompt를 이용해 입력받는다. 
const userStorage = new UserStorage();
const id = prompt("enter your id");
const password = prompt("enter your password");

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

콜백함수 부분만 떼어놓고 보자 !

우선 코드 작성할 때도 내가 작성하기도 헷갈렸고,
작성하지 않는 사람이 보기에 이해하기가 쉽지 않다고 바로 느껴졌다.
가독성이 너무 떨어져서 어떻게 연결되는지 한번에 보기가 어려운 문제점이있다.


Promise

위와 같이 콜백지옥을 Promise를 통하여 간결하게 만들 수 있다.
class UserStorage {
  loginUser(id, password) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (
          (id === "hyejin" && password === "dream") ||
          (id === "corder" && password === "academy")
        ) {
          resolve(id);
        } else {
          reject(new Error("not found"));
        }
      }, 2000);
    });
  }

  getRoles(user) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (user === "hyejin") {
          resolve({ name: "hyejin", role: "admin" });
        } else {
          reject(new Error("no access"));
        }
      }, 1000);
    });
  }
}

//prompt로 id password 입력받기.
const userStorage = new UserStorage();
const id = prompt("enter your id");
const password = prompt("enter your password");

userStorage
  .loginUser(id, password)
  .then(userStorage.getRoles) //.then((id)=>userStorage.getRoles(id))
  .then((user) => alert(`Hello ${user.name}, you have a ${user.role} role`))
  .catch(colsole.log); // .catch((e) => colsole.log(e));

맨 아래를 보게될 경우, 간략해질 뿐 아니라 가독성까지 좋게 변했다.


참고 : https://www.youtube.com/watch?v=s1vpVCrT8f4&t=5s

0개의 댓글