callback : 함수의 인수로 사용하는 또 다른 함수
// a b c d 의 호출 순서를 보장
function a(callback) {
  setTimeout(() => {
    console.log('A')
    callback()
  }, 1000)
}

function b(callback) {
  setTimeout(() => {
    console.log('B')
    callback()
  }, 1000)
}

function c(callback) {
  setTimeout(() => {
    console.log('C')
    callback()
  }, 1000)
}

function d(callback) {
  setTimeout(() => {
    console.log('D')
    callback()
  }, 1000)
}

a(function() {
  b(function() {
    c(function() {
      d(function() {
        console.log('Done!')
      })
    })
  })
})

// **그렇지만 콜백지옥이 나타난다!!**
// 콜백이 다음 순서를 보장해주는 장점을 가지고는 있지만 이렇게 계속 파고들면
// 후에 관리하기 매우 힘들어진다. 이를 해결하기 위함이 **Promise** 객체이다.
// function a(callback) {
//   setTimeout(() => {
//     console.log('A')
//     callback()
//   }, 1000)
// }
function a () {
  // promise 약속의 객체를 반환!
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log('A')
      resolve('pass this message')
    }, 1000);
  })
}

function b () {
  console.log('B')
}

async function test() {
  // 반환받은 promise 객체에 await 키워드를 붙일 수 있다.
  // resolve() 매개변수가 실행될 때 까지 기다려준다.
  const res = await a()
  console.log('res : ', res) // res :  pass this message
  b()
}

test()
// A
// res :  pass this message
// D
// function a(callback) {
//   setTimeout(() => {
//     console.log('A')
//     callback()
//   }, 1000)
// }
function a () {
  // promise 약속의 객체를 반환!
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log('A')
      resolve('pass A message')
    }, 1000);
  })
}

function b () {
  // promise 약속의 객체를 반환!
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log('B')
      resolve('pass B message')
    }, 1000);
  })
}

function c () {
  // promise 약속의 객체를 반환!
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log('C')
      resolve('pass C message')
    }, 1000);
  })
}

function d () {
  // promise 약속의 객체를 반환!
  return new Promise(function(resolve) {
    setTimeout(() => {
      console.log('D')
      resolve('pass D message')
    }, 1000);
  })
}

async function test() {
  let msg = await a()
  console.log(msg)
  msg = await b()
  console.log(msg)
  msg = await c()
  console.log(msg)
  msg = await d()
  console.log(msg)
}

test()