Callback

Juhwan Lee·2021년 11월 18일
0
post-thumbnail

1. 동기와 비동기

JavaScript is synchronous!
🔥 자바스크립트는 동기적이다 🔥

hoisting이 된 이후부터, code가 작성한 순서에 맞춰서 하나 하나씩 동기적으로 실행된다.

hoisting: var, function declaration이 자동적으로 맨 위로 올라가는 것을 말한다.

console.log('1');
// browser에게 요청하고 결과 값을 받는다. - 비동기적 방식
setTimeout(() => console.log('2'), 1000); // 지정한 시간이 지나면 콜백함수 호출
console.log('3');

// 위 처럼 작성시 console에는
1
3
2
// 순으로 나타나게 된다.

2. 콜백함수도 2가지로 나누어 진다

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

// Asynchronous callback
function printWithDelay(print, timeout) {
  setTimeout(print, timeout);
}
printWithDelay(() => console.log('async callback'), 2000);

3. 콜백 지옥 체험

콜백은 유용하게 쓰이지만, 콜백 지옥을 만들 수도 있다

class UserStorage {
  loginUser(id, password, onSuccess, onError) {
    setTimeout(() => {
      if (
        (id === 'lee' && password === 'ju' ||
        (id === 'hwan' && password === 'wow')
      ) {
        onSuccess(id);
      } else {
        onError(new Error('not found'));
      }
    }, 2000);
  }
  
  getRoles(user, onSuccess, onError) {
    setTimeout(() => {
      if (user === 'lee') {
        onSuccess({ name: 'lee', role: 'admin' });
      } else {
        onError(new Error('no access'));
      }
    }, 1000);
  }
}

원하는 로직
1. 사용자에게 'id' 'password'를 입력 받아 온다.
2. server에 입력된 정보를 보내 login을 한다.
3. 받아온 id를 이용해서 역할을 요청한다.
4. 역할을 받아와서 출력한다.

const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your passrod');
userStorage.loginUser(
  id,
  password,
  user => {
    userStorage.getRoles(
      user,
      userWithRole => {
        alert(
          `Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
        );
      },
      error => {
        console.log(error);
      }
    );
  },
  error => {
    console.log(error);
  }
);

4. 콜백 체인의 문제점

  1. 가독성이 너무 떨어진다.
  2. 디버깅, 유지보수를 해야하는 경우에 너무 어렵다.

5. 콜백 지옥을 Promise로

class UserStorage {
  loginUser(id, password) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (
          (id === 'ellie' && password === 'dream') ||
          (id === 'coder' && password === 'academy')
        ) {
          resolve(id);
        } else {
          reject(new Error('not found'));
        }
      }, 2000);
    });
  }

  getRoles(user) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (user === 'ellie') {
          resolve({ name: 'ellie', role: 'admin' });
        } else {
          reject(new Error('no access'));
        }
      }, 1000);
    });
  }
  
const userStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt('enter your passrod');
userStorage
  .loginUser(id, password)
  .then(userStorage.getRoles)
  .then(user => alert(`Hello ${user.name}, you have a ${user.role} role`))
  .catch(console.log);




출처
'드림코딩'님의 비동기 처리의 시작 콜백 이해하기

profile
keep going

0개의 댓글