[6] Callback & Promise

NaakiteΒ·2022λ…„ 2μ›” 14일
0

πŸ“λ“œλ¦Όμ½”λ”© JavaScript

λͺ©λ‘ 보기
6/6
post-thumbnail

πŸ“Œ 동기, 비동기


μžλ°”μŠ€ν¬λ¦½νŠΈ μ–Έμ–΄λŠ” 동기적 언어이닀.
동기적 μ–Έμ–΄λž€ μœ„μ—μ„œ λΆ€ν„° μ•„λž˜λ‘œ 순차적으둜 μ½”λ“œκ°€ μ§„ν–‰λ˜λŠ” 것을 λ§ν•œλ‹€.
그럼 비동기적 μ–Έμ–΄λŠ” λ¬΄μ—‡μΌκΉŒ?
μ–΄λ–€ μž‘μ—…μ„ μš”μ²­ν•˜λ©΄ κ·Έ μž‘μ—…μ΄ μ’…λ£Œλ λ•ŒκΉŒμ§€ 기닀리고 κ·Έ λ‹€μŒ μž‘μ—…μ„ ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, μ—¬λŸ¬ μž‘μ—…μ„ λ™μ‹œμ— ν•˜λŠ” 것을 λ§ν•œλ‹€.

🏁 μ½œλ°±ν•¨μˆ˜λž€?

ν•¨μˆ˜μ˜ λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 λ‹€λ₯Έ ν•¨μˆ˜μ˜ λ‚΄λΆ€λ‘œ μ „λ‹¬λ˜λŠ” ν•¨μˆ˜.
μ–΄λ–€ μ΄λ²€νŠΈμ— μ˜ν•΄ ν˜ΈμΆœλ˜μ–΄μ§€λŠ” ν•¨μˆ˜.
λ‚˜μ€‘μ— ν˜ΈμΆœλ˜λŠ” ν•¨μˆ˜.

λŒ€ν‘œμ μΈ μ½œλ°±ν•¨μˆ˜λ‘œλŠ” setTimeout 이 μžˆλ‹€.

console.log('1');
setTimeout(()=>
 console.log('2');
, 1000) //1초 후에 2좜λ ₯
console.log('3');
// 1,3,2

그럼 μ½œλ°±ν•¨μˆ˜λŠ” λΉ„λ™κΈ°μΌλ•Œλ§Œ μ‚¬μš©ν• κΉŒ? ❌

μ½œλ°±ν•¨μˆ˜λ„ λ™κΈ°μ μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.

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

printλΌλŠ” μ½œλ°±μ„ λ°›μ•„μ„œ printλ₯Ό λ°”λ‘œ μ‹€ν–‰ν•œλ‹€.

function printImmediately (print) {
  print();
}
function printWithDelay (print, timeout) {
  setTimeout(print, timeout);
}
console.log('1');
setTimeout(()=>console.log('2'), 1000);
console.log('3');
printImmediately(()=> console.log('hello'));
printWithDelay(()=> console.log('async callback'),2000); 
 // 1 , 3 , hello , 2 μˆœμ„œλŒ€λ‘œ 좜λ ₯λœλ‹€.

πŸ”₯ 콜백 지μ˜₯

유튜브 λ“œλ¦Όμ½”λ”©μ—μ„œ κ°„λ‹¨ν•œ μ½œλ°±μ§€μ˜₯을 λ§Œλ“€μ–΄λ³΄μ•˜λ‹€. μ½”λ“œλ₯Ό 보며 μ½œλ°±μ§€μ˜₯이 뭔지 μ΄ν•΄ν•΄λ³΄μž!🧐

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

  }
  getRoles(user, onSuccess, onError){
    setTimeout(()=>{
      if(user === 'ellie'){
        onSuccess({name: 'ellie', role: 'admin'});
      }
      else{
        onError(new Error('no access'));
      }
    },1000);
  }
}
// μœ μ €μ˜ 정보λ₯Ό κ°€μ Έμ˜€λŠ” 것이닀.


const UserStorage = new UserStorage();
const id = prompt('enter your id');
const password = prompt ('enter your password');
// μ‚¬μš©μžμ˜ 아이디와 νŒ¨μŠ€μ›Œλ“œλ₯Ό μž…λ ₯λ°›λŠ”λ‹€. 
UserStorage.loginUser(
  id,   // μž…λ ₯받은 아이디와 νŒ¨μŠ€μ›Œλ“œλ₯Ό loginUser으둜 μ „λ‹¬ν•˜μ—¬ 둜그인이 λ˜μ—ˆλ‹€λ©΄
  password, 
  (user)=>{ /// μ„±κ³΅ν•œλ‹€λ©΄ μ‚¬μš©μžμ˜ μ—­ν•  확인
    UserStorage.getRoles(
      user, 
      userWithRole => {
        alert(
          `Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
        );
      },
      error => { // μ‚¬μš©μžμ˜ 역할을 λ°›μ•„μ˜€μ§€ λͺ»ν–ˆμ„ λ•Œ
        console.log(error);
      }
    );
  },
  error => { // λ‘œκ·ΈμΈμ„ ν•˜μ§€ λͺ»ν–ˆμ„ λ•Œ
    console.log(error);
  }
    )

μ΄λ ‡κ²Œ μ½œλ°±ν•¨μˆ˜ μ•ˆμ—μ„œ μ½œλ°±ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , 또 κ·Έ ν•¨μˆ˜μ•ˆμ— μ½œλ°±ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 것을 μ½œλ°±μ§€μ˜₯이라고 ν•œλ‹€.
μ§€κΈˆμ€ μ½”λ“œκ°€ 짧은 νŽΈμ΄μ§€λ§Œ, λ§Œμ•½ μ‹€μ œ ν˜„μ—…μ—μ„œ μ΄λ ‡κ²Œ μ½œλ°±ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€λ©΄, 가독성이 쒋지 μ•Šκ³ , λΉ„μ§€λ‹ˆμŠ€ λ‘œμ§μ„ νŒŒμ•…ν•˜κΈ° μ–΄λ ΅κ³ , 디버깅, μ—λŸ¬ μ²˜λ¦¬κ°€ μ–΄λ ΅λ‹€. 또, μœ μ§€λ³΄μˆ˜κ°€ μ–΄λ ΅λ‹€λŠ” 단점이 μžˆλ‹€.

🏁 μ½œλ°±μ§€μ˜₯ ν•΄κ²°μ±… = Promise

βœ… Promise?

μΆ”μƒμ μœΌλ‘œ μ„€λͺ…ν•˜μžλ©΄, λ§Œμ•½ 아직 μΆœμ‹œλ˜μ§€ μ•Šμ€ μˆ˜μ—…μ„ Aμ‚¬μš©μžκ°€ 미리 이메일을 λ“±λ‘ν•˜μ—¬ μˆ˜μ—… μΆœμ‹œλ˜λŠ” λ‚  μ΄λ©”μΌλ‘œ μ „μ†‘λ μˆ˜ 있게 μ˜ˆμ•½μ„ ν•œ ν›„ (promise 등둝), μˆ˜μ—…μ΄ μΆœμ‹œλœ λ‚  Aμ‚¬μš©μžμ—κ²Œ 이메일이 μ „μ†‘λœλ‹€.(Promiseκ°€ μ„±κ³΅μ μœΌλ‘œ κ°’ 전달)
μˆ˜μ—…μ΄ μΆœμ‹œλœ ν›„ Bμ‚¬μš©μžκ°€ 이메일 λ“±λ‘λ²„νŠΌμ„ λˆ„λ₯΄λ©΄, 이미 μΆœμ‹œλœ 후이기에 기닀릴 ν•„μš”μ—†μ΄ 이메일이 λ°”λ‘œ μ „μ†‘λœλ‹€.(이미 μ„±κ³΅μ μœΌλ‘œ 처리된 Promise)

μ‰½κ²Œ 말해, 비동기λ₯Ό κ΅¬ν˜„ν•  λ•Œ μ‚¬μš©λ˜λŠ” 객체이닀.

ν”„λ‘œλ―ΈμŠ€λŠ” μƒνƒœμ •λ³΄λ₯Ό κ°€μ§€λŠ”λ°,
panding(비동기 μ²˜λ¦¬κ°€ 아직 μˆ˜ν–‰λ˜μ§€ μ•Šμ€ μƒνƒœ = ν”„λ‘œλ―ΈμŠ€κ°€ μƒμ„±λœ 직후 κΈ°λ³Έ μƒνƒœ),
fulfilled(비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœ(성곡)= resolve ν•¨μˆ˜ 호좜),
rejected(비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœ(μ‹€νŒ¨)= reject ν•¨μˆ˜ 호좜),
seletted(비동기 처리 성곡,μ‹€νŒ¨μ™€ 상관없이 비동기 μ²˜λ¦¬κ°€ μˆ˜ν–‰λœ μƒνƒœ) κ°€ μžˆλ‹€.

βœ… Producer?

Promise μƒμ„±μž ν•¨μˆ˜λ₯Ό new μ—°μ‚°μžμ™€ ν•¨κ»˜ ν˜ΈμΆœν•˜λ©΄, Promise 객체λ₯Ό μƒμ„±ν•œλ‹€. 비동기 처리λ₯Ό μˆ˜ν–‰ν•  μ½œλ°±ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ°, 이 μ½œλ°±ν•¨μˆ˜λŠ” resolve 와 reject ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€. 인수둜 전달받은 콜백 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ 비동기 처리λ₯Ό μˆ˜ν–‰ν•˜κ³ , λ§Œμ•½ 비동기 처리λ₯Ό μ„±κ³΅ν•˜λ©΄ resolve ν•¨μˆ˜λ₯Ό, λ§Œμ•½ μ‹€νŒ¨ν•˜λ©΄ reject ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

const promise = new Promise((resolve, reject) => {
  if (/*비동기 처리 성곡*/) {
      resolve('result');
   }
  else {/*비동기 처리 μ‹€νŒ¨*/
      reject('error');
   }
});

βœ… Consumer?

λ§Œλ“€μ–΄μ§„ ν”„λ‘œλ―ΈμŠ€ 객체 μ‚¬μš©. then , catch , finally 이 μžˆλ‹€.

Promise.prototype.then

then λ©”μ„œλ“œλŠ” 비동기 μ²˜λ¦¬κ°€ μ„±κ³΅ν–ˆμ„ λ•Œ ν˜ΈμΆœλ˜λŠ” μ½œλ°±ν•¨μˆ˜(resolve),
비동기 μ²˜λ¦¬κ°€ μ‹€νŒ¨ν–ˆμ„ λ•Œ ν˜ΈμΆœλ˜λŠ” μ½œλ°±ν•¨μˆ˜(reject) 총 두 개의 콜백 ν•¨μˆ˜λ₯Ό 인수둜 μ „λ‹¬λ°›λŠ”λ‹€.

Promise.prototype.catch

ν”„λ‘œλ―ΈμŠ€κ°€ rejected μƒνƒœμΈ κ²½μš°μ—λ§Œ ν˜ΈμΆœλœλ‹€.

Promise.prototype.finally

ν”„λ‘œλ―ΈμŠ€μ˜ 성곡, μ‹€νŒ¨μ™€ 상관없이 무쑰건 ν•œλ²ˆ ν˜ΈμΆœλœλ‹€.

βœ… Promise error

const getHen = () => 
  new Promise((resolve, reject)=>{
    setTimeout(() => resolve('πŸ”'), 1000);
  });
const getEgg = hen => 
  new Promise((resolve, reject)=>{
    setTimeout(() => reject(new Error(`error! ${hen} =>πŸ₯š`)), 1000);
  });
const cook = egg => 
  new Promise((resolve, reject)=>{
    setTimeout(() => resolve(`${egg} => 🍳`), 1000);
  });
getHen()
  .then(getEgg)
  .then(cook) 
  .catch(console.log)
  .then(console.log)

🧐 μ½œλ°±μ§€μ˜₯ ν•΄κ²°!

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 password');
UserStorage
  .loginUser(id, password)
  .then(UserStorage.getRoles)
  .then(user => alert(
    `Hello ${userWithRole.name}, you have a ${userWithRole.role} role`
  ))
  .cathch(console.log);

μ΄λ ‡κ²Œ ν•΄κ²°ν•  수 μžˆλ‹€! 많이 직접 κ΅¬ν˜„ν•˜λ©΄μ„œ μ΅ν˜€λ‚˜κ°€μ•Ό ν•  것 κ°™λ‹€!πŸ’ͺ


λ“œλ¦Όμ½”λ”© κ°•μ˜λ₯Ό λ“£κ³  μž‘μ„±ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

profile
πŸ‘©β€πŸ’»πŸƒβ€β™€οΈ

0개의 λŒ“κΈ€