개발 공부/자바스크립트

[엘리의 드림코딩 JS] 13. async, await

5묘 2022. 12. 6. 15:11

https://youtu.be/aoQSOZfz3vQ

Promise 를 조금 더 간결하고, 동기적으로 보이게 만들어주는 것이 async, await!
기존에 존재하는 기능을 더 좋아보이게 만드는 Syntatic sugar 로 볼 수 있다.

// async & await
// clear style of using promise :)

//1. async
async function fetchUser() {
  // do network request in 10 secs...
  return 'ellie';
}

const user = fetchUser();
user.then(console.log);
console.log(user);


// 2. await ✨
function delay(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

async function getApple() {
  await delay(2000);
  return '🍎';
}

async function getBanana() {
  await delay(1000); 
  return '🍌';
}
//이거랑 같은데 await을 쓰면 보다 동기적으로 보인다.
// function getBanana () {
//   return delay(3000)
//   .then(() =>'🍌')
// }

// function pickFruits() {
//   return getApple().then(apple => {
//     return getBanana().then(banana => `${apple} + ${banana}`);
//   });
// }

// pickFruits().then(console.log);

async function pickFruits() {
  const applePromise = getApple();
  const bananaPromise = getBanana(); // 이렇게 하면 병렬적으로 동시에 사과, 바나나 따고
  const apple = await applePromise;  // 순차적으로 사과, 바나나를 출력할 수 있다.(효율성 증가)
  const banana = await bananaPromise;// 하지만 이렇게 작성하는 건 너무 더러우니 3번의 Promise.all() API 사용한다.
  return `${apple} + ${banana}`; 
}

pickFruits().then(console.log);


// 3. useful Promise APIs
function pickAllFruits() {
  return Promise.all([getApple(), getBanana()])
  .then(fruits => fruits.join(' + '))
}
pickAllFruits().then(console.log);

// if 순서 상관 없이 먼저 따지는 과일을 먼저 받아오겠다!
function pickOnlyOne() {
  return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log);

HomeWork : 어제 callback hell을 Promise로 해결한 문제를 Async await으로 더 간결하게 만들어보자!

// Homework(Promise => async,await)
// class 내 메서드에는 async await 적용시킬 방법 없나...?
class UserStorage {
  loginUser = (id, password) => 
    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) => 
    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 password')

// 여기 아래를 수정함
async function signIn() {
  const user = await userStorage.loginUser(id, password)
  const userWithRole = await userStorage.getRoles(user);
  return userWithRole;  
}

signIn().then((user) => alert(`hello ${user.name}, you have a ${user.role} role.`));


// 댓글에서 본 좀 더 괜찮은 답
// error을 string으로 출력하도록 handling해주어 프로그램이 멈추지 않게 했다(중요!)
async function checkUser() {
  try {
    const userId = await userStorage.loginUser(id, password);
    const user = await userStorage.getRoles(userId);
    alert(`hello ${user.name}, you have a ${user.role} role.`);
  } catch(error) {
    console.log(error);
  }
};

checkUser();