[aboutJS] async(a.k.a 콜백지옥)

Adela·2020년 9월 2일
1

aboutJS

목록 보기
9/9
post-thumbnail

참고영상 : 드림코딩 | 자바스크립트 기초 강의

우리 JavaScript는요..

  • synchronous, 동기적이고
  • hoisting 이후, 순서에 따라 코드 블럭을 수행한다.

hoisting;
var, function 과 같은 선언들이 자동적으로 코드 제일 위로 올라가는 것

console.log('1')
console.log('2')
console.log('3')
1
2
3

으로 출력된다. 자명하다.
그러나, setTimeout()을 사용하면 어떻게될까?

console.log('1')
setTimeout(() => {
    console.log("2")
}, 1000) 
console.log('3')
1
3
(1초 뒤에)
2 

setTimeout()이 걸린 함수는 바로 실행되지 않는다. 우리가 만든 함수를 전달만 하고, 나중에 우리가 지정한 시간 뒤에 실행하게 된다.
여기서 작성한 함수가 '나중에 다시 불러줘!!' => callback 함수

🖐🏻 그럼 콜백은 비동기일 때만 씀?

1. synchronous callback

console.log('1')
setTimeout(() => {
    console.log("2")
}, 1000) 
console.log('3')
function printImmediatly(print) {
    print()
}
printImmediatly(() => console.log('hello'))

이 코드의 결과는?

1
3
hello
2

순서

  1. function printImmediatly(print)는 hoisting되어 맨 위로 올라간다.
  2. console.log('1') 실행한다.
  3. setTimeout에 우리가 만든 함수를 전달만 한다. 일단 전달만..
  4. console.log('3') 실행한다.
  5. printImmediatly(() => console.log('hello')) 실행한다.
  6. setTimeout에 걸려있던 함수를 실행한다.

asynchronous callback

console.log('1')
setTimeout(() => {
    console.log("2")
}, 1000) 
console.log('3')
function printWithDelay(print, timeout) {
    setTimeout(print, timeout)
} 

printWithDelay(() => console.log("async callback world"), 2000) // 

이 코드의 결과는?

1
3
2
async callback world

순서

  1. function printImmediatly(print, timeout)는 hoisting되어 맨 위로 올라간다.
  2. console.log('1') 실행한다.
  3. setTimeout에 우리가 만든 함수를 전달만 한다. 일단 전달만..
  4. console.log('3') 실행한다.
  5. printImmediatly(() => console.log('async callback world'), 1000) 을 실행하려고 보니.. 어라? setTimeout이네? 전달만 한다.
  6. setTimeout에 걸려있던 함수를 실행한다. => 2
  7. setTimeout에 걸려있던 함수를 실행한다. => async callback world

📌 물론 setTimeout에 걸린 시간에 따라 나중의 것이 더 먼저 출력될 수도 있지만, 같은 시간일 경우에는 먼저 전달된 함수가 실행된다.

콜백지옥

간단한 로그인 기능을 구현한다.
1. 아이디, 비번을 받아오면 로그인 성공인지 실패인지 띄운다.
2. 로그인이 성공이면 => 아이디에 따라 어떤 role을 갖고 있는지 알려준다.

class UserStorage {
    loginUser(id, password, onSuccess, onError) {
      // id, password 받고 나서 판별 후 onSuccess or onError를 콜백으로!
        setTimeout(() => {
            if ((id === 'yang' && password === '1234') ||
                (id === 'kim' && password === '4321')) {
                onSuccess(id)
            } else {
                onError(new Error('not found'))
            }
        }, 2000)
    }

    getRoles(user, onSuccess, onError) {
        setTimeout(() => {
            if (user === 'yang') {
                onSuccess({
                    name: 'yang',
                    role: 'admin'
                })
            } else {
                onError(new Error('no access'))
            }
        }, 1000)
    }
}

class를 실행시킬 코드를 짠다.

const userStorage = new UserStorage()
const id = prompt('enter your id')
const password = prompt('enter your password')
userStorage.loginUser(
    id,
    password,
    user => { // 로그인 성공하면 
        userStorage.getRoles(user,
            (userWithRole) => { // 해당 유저가 role 가진 유저면 
                alert(`hello ${userWithRole.name}, you have a ${userWithRole.role} role`)
            },
            (error) => { // role 가진 유저가 아니면 
                console.log(error)
            })
    },
    error => { // 로그인 실패하면
        console.log(error)
    }
)

즉, 이렇게 콜백이 계속 nested되는 지옥 현상이 발생하게 된다 ...
이에 따라 다음 시간엔 Promise를 배우기로.. ㅎㅎ

profile
개발 공부하는 심리학도

1개의 댓글

comment-user-thumbnail
2020년 12월 11일

오 이해하기 쉽네요! 😀

답글 달기