[TIL] 211012

Lee SyongΒ·2021λ…„ 10μ›” 12일
0

TIL

λͺ©λ‘ 보기
55/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. promise / promiseStatus / executor / resolve / reject / then / catch / finally / promise chaining(ν”„λ‘œλ―ΈμŠ€ μ—°κ²°) / μ—λŸ¬ 처리 / 콜백 지μ˜₯ νƒˆμΆœν•˜κΈ° / async

πŸ“– ν•™μŠ΅ 자료

  1. λ“œλ¦Όμ½”λ”© 유튜브 'μžλ°”μŠ€ν¬λ¦½νŠΈ 기초 κ°•μ˜' 12 ~ 13편

πŸ“š 배운 것

1. Promise(ν”„λ‘œλ―ΈμŠ€)

  • 비동기 처리λ₯Ό κ°„νŽΈν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ”, μžλ°”μŠ€ν¬λ¦½νŠΈ λ‚΄μž₯ 였브젝트

  • 정해진 μž₯μ‹œκ°„μ˜ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜κ³  λ‚˜μ„œ, μ •μƒμ μœΌλ‘œ κΈ°λŠ₯이 μˆ˜ν–‰λλ‹€λ©΄ 처리된 κ²°κ³Ό 값을 μ „λ‹¬ν•˜κ³ , λ¬Έμ œκ°€ λ°œμƒν–ˆλ‹€λ©΄ μ—λŸ¬λ₯Ό μ „λ‹¬ν•œλ‹€.

    ex) 등둝 λ²„νŠΌμ„ 눌러 이메일을 μž…λ ₯ν•΄ κ²Œμž„μ„ 사전 μ˜ˆμ•½ 해두면, κ²Œμž„μ΄ μ˜€ν”ˆλ˜μžλ§ˆμž μ΄λ©”μΌλ‘œ 곡지λ₯Ό 받을 수 μžˆλ‹€. ν•œνŽΈ, κ²Œμž„μ΄ μ˜€ν”ˆλœ ν›„ 등둝 λ²„νŠΌμ„ λˆ„λ₯΄λ©΄, 이미 κ²Œμž„μ΄ μ˜€ν”ˆλœ ν›„μ΄λ―€λ‘œ 기닀릴 ν•„μš” 없이 λ°”λ‘œ μ΄λ©”μΌλ‘œ 곡지λ₯Ό λ°›κ²Œ λœλ‹€.


1) 곡뢀 point !

1) status

ν”„λ‘œμ„ΈμŠ€κ°€ 처리λ₯Ό μˆ˜ν–‰ 쀑인지
μˆ˜ν–‰μ΄ μ™„λ£Œλ˜μ–΄ μ„±κ³΅ν–ˆλŠ”μ§€ μ‹€νŒ¨ν–ˆλŠ”μ§€

  • pending
    μ§€μ •ν•œ 처리λ₯Ό μˆ˜ν–‰ 쀑일 λ•Œ
  • fullfilled
    처리λ₯Ό μ„±κ³΅μ μœΌλ‘œ λλƒˆμ„ λ•Œ
  • rejected
    νŒŒμΌμ„ 찾을 수 μ—†κ±°λ‚˜ λ„€νŠΈμ›Œν¬μ— λ¬Έμ œκ°€ 생겼을 λ•Œ

2) Producer와 Consumer

  • Producer
    μ§€μ •ν•œ 처리λ₯Ό μˆ˜ν–‰ν•˜μ—¬ 데이터λ₯Ό μ œκ³΅ν•œλ‹€
    μ—¬κΈ°μ„œλŠ” promiseκ°€ ν•΄λ‹Ήλœλ‹€
  • Consumer
    μ›ν•˜λŠ” 데이터λ₯Ό μ†ŒλΉ„ν•œλ‹€

2) Promise 생성

promiseλŠ” μš°λ¦¬κ°€ μ›ν•˜λŠ” κΈ°λŠ₯을 λΉ„λ™κΈ°μ μœΌλ‘œ μˆ˜ν–‰ν•œλ‹€
μ§€μ •ν•œ 처리λ₯Ό μˆ˜ν–‰ν•΄ consumerμ—κ²Œ 데이터λ₯Ό μ œκ³΅ν•˜λŠ” producer에 ν•΄λ‹Ήν•œλ‹€


const promise = new Promise((resolve, reject) => {
  // 보톡 λ‹€μ†Œ μ‹œκ°„μ΄ κ±Έλ¦¬λŠ” 무거운 κΈ°λŠ₯을 μˆ˜ν–‰ν•œλ‹€ (λ„€νŠΈμ›Œν¬ 톡신, 파일 μ½μ–΄μ˜€κΈ°)
});

πŸ’‘ promiseλŠ” μ˜€λΈŒμ νŠΈμ΄λ―€λ‘œ, Promise μƒμ„±μž ν•¨μˆ˜λ₯Ό 톡해 생성할 수 μžˆλ‹€.

promise μƒμ„±μž ν•¨μˆ˜λŠ” executorλΌλŠ” 콜백 ν•¨μˆ˜λ₯Ό 인자둜 μ „λ‹¬λ°›λŠ”λ‹€. executorλŠ” resolve와 rejectλΌλŠ” 2가지 콜백 ν•¨μˆ˜λ₯Ό 인자둜 μ „λ‹¬λ°›λŠ”λ‹€.

  • resolve
    κΈ°λŠ₯을 μ •μƒμ μœΌλ‘œ μˆ˜ν–‰ν•œ ν›„ λ§ˆμ§€λ§‰μ— μ΅œμ’… 데이터λ₯Ό 전달할 λ•Œ ν˜ΈμΆœλœλ‹€.
  • reject
    κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ‹€ λ¬Έμ œκ°€ 생기면 ν˜ΈμΆœλœλ‹€.

const promise = new Promise((resolve, reject) => {
  console.log('doing something...');
});
// console 창에 λ°”λ‘œ 좜λ ₯λœλ‹€.

πŸ’‘ 그런데 promiseκ°€ μƒμ„±λœ μˆœκ°„, Promise μƒμ„±μž ν•¨μˆ˜μ— 인자둜 μ „λ‹¬ν•œ executor(콜백 ν•¨μˆ˜)κ°€ λ°”λ‘œ μ‹€ν–‰λœλ‹€.

λ”°λΌμ„œ, λ§Œμ•½ λ„€νŠΈμ›Œν¬ μš”μ²­μ„ μ‚¬μš©μžκ°€ μš”κ΅¬ν–ˆμ„ λ•Œλ§Œ ν•΄μ•Ό ν•˜λŠ” 경우라면, μ‚¬μš©μžκ°€ μš”κ΅¬ν•˜μ§€λ„ μ•Šμ•˜λŠ”λ° λΆˆν•„μš”ν•œ λ„€νŠΈμ›Œν¬ 톡신이 μΌμ–΄λ‚˜κ²Œ λœλ‹€. 항상 이λ₯Ό μœ μ˜ν•΄μ„œ promiseλ₯Ό μž‘μ„±ν•΄μ•Ό ν•œλ‹€.


const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('syong');
  }, 2000);
});

πŸ’‘ setTimeout을 톡해 λ„€νŠΈμ›Œν¬ 톡신을 ν•˜λŠ” κ²ƒμ²˜λŸΌ delayλ₯Ό μ€˜μ„œ μœ„μ™€ 같이 promiseλ₯Ό 생성할 수 μžˆλ‹€.

promiseλŠ” 2초 λ™μ•ˆ μ–΄λ–€ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ”λ°(μ‹€μ œλΌλ©΄ 'μ–΄λ–€ κΈ°λŠ₯'은 λ„€νŠΈμ›Œν¬ 톡신, 파일 μ½μ–΄μ˜€κΈ° 등이 ν•΄λ‹Ήν•œλ‹€.)
κ²°κ΅­ 이λ₯Ό μ„±κ³΅μ μœΌλ‘œ μˆ˜ν–‰ν•œ 경우, resolveλΌλŠ” 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.
resolve ν•¨μˆ˜λŠ” syongμ΄λΌλŠ” 데이터λ₯Ό μ΅œμ’…μ μœΌλ‘œ 전달해쀀닀.


3) then, catch, finally

then, catch, finallyλ₯Ό μ΄μš©ν•΄ promiseλ‘œλΆ€ν„° μ›ν•˜λŠ” 데이터λ₯Ό λ°›μ•„μ˜¬ 수 μžˆλ‹€
이듀은 promiseλ₯Ό μ΄μš©ν•˜λŠ” consumer에 ν•΄λ‹Ήν•œλ‹€


πŸ’‘ promiseμ—μ„œ κΈ°λŠ₯이 μ„±κ³΅μ μœΌλ‘œ μˆ˜ν–‰λλ‹€λ©΄, then()을 μ΄μš©ν•΄ κ·Έ 데이터(value)λ₯Ό 받아와 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€.

promise.then(value => {
  console.log(value);
});

μœ„ 예제의 경우, valueμ—λŠ” promiseμ—μ„œ resolve ν•¨μˆ˜λ₯Ό 톡해 λ°›μ•„μ˜¨ syongμ΄λΌλŠ” 데이터가 μ „λ‹¬λœλ‹€.
promiseκ°€ μ„±κ³΅μ μœΌλ‘œ μˆ˜ν–‰λœ ν›„(2초 뒀에) console 창에 syong이 좜λ ₯λœλ‹€.


πŸ’‘ promiseμ—μ„œ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ‹€ λ¬Έμ œκ°€ 생겼닀면, catch()λ₯Ό μ΄μš©ν•΄ κ·Έ 였λ₯˜ λ©”μ‹œμ§€(error)을 받아와 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€.

const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    // resolve('syong');
    reject(new Error('no network'));
  }, 2000);
});

promise
  .then(value => { // μ •μƒμ μœΌλ‘œ κΈ°λŠ₯ μˆ˜ν–‰ μ™„λ£Œ μ‹œ
    console.log(value);
  })
  .catch(error => { // κΈ°λŠ₯ μˆ˜ν–‰ 쀑 문제 λ°œμƒ μ‹œ
    console.log(error);
  });

μœ„ μ½”λ“œλŠ” chaining을 μ΄μš©ν•œ μ½”λ“œμ΄λ‹€.
promise μ˜€λΈŒμ νŠΈμ— then() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ promise 였브젝트λ₯Ό λ°˜ν™˜ν•œλ‹€.
λ°˜ν™˜λœ promise에 λ‹€μ‹œ catch() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ 것이닀.

μœ„ 예제의 경우, errorμ—λŠ” promiseμ—μ„œ reject ν•¨μˆ˜λ₯Ό 톡해 λ°›μ•„μ˜¨ 'no network'λΌλŠ” 였λ₯˜ λ©”μ‹œμ§€κ°€ μ „λ‹¬λœλ‹€.
promiseκ°€ κΈ°λŠ₯ μˆ˜ν–‰ 쀑 λ¬Έμ œκ°€ λ°œμƒν•˜λ©΄(2초 뒀에) console 창에 no networkκ°€ 좜λ ₯λœλ‹€.


πŸ’‘ finally()λŠ” promiseκ°€ κΈ°λŠ₯ μˆ˜ν–‰μ— μ„±κ³΅ν•˜λ“  μ‹€νŒ¨ν•˜λ“  상관없이, then() ν˜Ήμ€ catch()κ°€ 호좜된 ν›„, 무쑰건 λ§ˆμ§€λ§‰μ— ν˜ΈμΆœλœλ‹€.

promise
  .then(value => {
    console.log(value);
  })
  .catch(error => {
    console.log(error);
  })
  .finally(() => {
    console.log('finally');
  });

// console μ°½ 좜λ ₯ κ²°κ³Ό

// Error: no network
// finally

4) ν”„λ‘œλ―ΈμŠ€ μ—°κ²°(Promise Chaining)

then() λ©”μ„œλ“œλ₯Ό μ΄μš©ν•΄ λ‹€μˆ˜μ˜ 비동기 μ²˜λ¦¬λ“€μ„ λ¬Άμ–΄μ„œ μ²˜λ¦¬ν•  수 μžˆλ‹€.

// μ„œλ²„μ—μ„œ 숫자λ₯Ό λ°›μ•„μ˜€λŠ”(setTimeout으둜 λŒ€μ²΄) promiseλ₯Ό μƒμ„±ν•œλ‹€.
const fetchNumber = new promise((resolve, reject) => {
  setTimeout(() => resolve(1), 1000);
});

// `then()`을 μ΄μš©ν•΄ κ·Έ 데이터(value)λ₯Ό 받아와 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œλ‹€.
// then()은 promise의 값을 전달할 μˆ˜λ„ 있고, μƒˆλ‘œμš΄ promiseλ₯Ό 전달할 μˆ˜λ„ μžˆλ‹€.

fetchNumber
  .then(num => num * 2) // then()은 promiseλ‘œλΆ€ν„° 1의 값을 받아와, 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ ν›„, 2의 값을 κ°€μ§€λŠ” promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.
  .then(num => num * 3) // then()은 promiseλ‘œλΆ€ν„° 2의 값을 받아와, 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ ν›„, 6의 값을 κ°€μ§€λŠ” promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.
  .then(num => { // then()은 promiseλ‘œλΆ€ν„° 6의 값을 λ°›μ•„μ˜¨ ν›„, μƒˆλ‘œμš΄ promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.
    return new Promise((resolve, reject) => {
      setTimeout(() => resolve(num - 1), 1000);
      // 숫자λ₯Ό λ‹€λ₯Έ μ„œλ²„μ— 보내(setTimeout으둜 λŒ€μ²΄) λ‹€λ₯Έ 숫자둜 λ³€ν™˜λœ 값을 λ°›μ•„μ˜¨λ‹€.
      // μƒˆλ‘œμš΄ promise의 resolve ν•¨μˆ˜λŠ”, 6 - 1μ΄λΌλŠ” 값을 μ „λ‹¬ν•œλ‹€.
    });
  })
  .then(num => console.log(num)); // then()은 μƒˆλ‘œμš΄ promiseλ‘œλΆ€ν„° 5λΌλŠ” 값을 받아와, 이λ₯Ό 좜λ ₯ν•œλ‹€.

5) μ—λŸ¬ 처리(Error Handling)

μ—λŸ¬ 상황에 λ°˜μ‘ν•˜κ³ , μ—λŸ¬λ₯Ό λ³΅κ΅¬ν•˜λŠ” 것을 λ§ν•œλ‹€


πŸ’‘ μ•„λž˜μ˜ getHen, getEgg, cook ν•¨μˆ˜λŠ”, 각각 λ‹€λ₯Έ 값을 κ°€μ§€λŠ” promiseλ₯Ό λ¦¬ν„΄ν•œλ‹€.

const getHen = () =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve('πŸ“'), 1000);
  });

const getEgg = hen =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${hen} => πŸ₯š`), 1000);
  });

const cook = egg =>
  new Promise((resolve, reject) => {
    setTimeout(() => resolve(`${egg} => 🍳`), 1000);
  });

getHen() // getHen ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜μ—¬ 'πŸ“'을 κ°’μœΌλ‘œ κ°€μ§€λŠ” promiseλ₯Ό λ§Œλ“ λ‹€.
  .then(hen => getEgg(hen)) // 'πŸ“'μ΄λΌλŠ” κ°’(hen)을 받아와 getEgg 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ ν›„ 'πŸ“ => πŸ₯š'을 κ°’μœΌλ‘œ κ°€μ§€λŠ” promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.
  .then(egg => cook(egg)) // 'πŸ“ => πŸ₯š'μ΄λΌλŠ” κ°’(egg)을 받아와 cook 콜백 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•œ ν›„ 'πŸ“ => πŸ₯š => 🍳'λ₯Ό κ°’μœΌλ‘œ κ°€μ§€λŠ” promiseλ₯Ό λ°˜ν™˜ν•œλ‹€.
  .then(meal => console.log(meal)); // 'πŸ“ => πŸ₯š => 🍳'μ΄λΌλŠ” κ°’(meal)을 받아와 이λ₯Ό 좜λ ₯ν•œλ‹€.

νŽ˜μ΄μ§€λ₯Ό μƒˆλ‘œκ³ μΉ¨ ν•œ ν›„ 3μ΄ˆκ°€ μ§€λ‚˜λ©΄, console 창에 'πŸ“ => πŸ₯š => 🍳'κ°€ 좜λ ₯λœλ‹€.


πŸ’‘ μ΄λ•Œ, getEgg ν•¨μˆ˜μ—μ„œ promiseκ°€ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ‹€κ°€ λ¬Έμ œκ°€ 생겼닀고 κ°€μ •ν•˜μž. getEgg ν•¨μˆ˜μ˜ setTimeout μ•ˆμ˜ resolve ν•¨μˆ˜λ₯Ό reject ν•¨μˆ˜λ‘œ λ°”κΏ”μ λŠ”λ‹€.

const getEgg = hen =>
  new Promise((resolve, reject) => {
    setTimeout(() => reject(new Error(`error! ${hen} => πŸ₯š`)), 1000);
  });

μ˜λ„ν•œ λŒ€λ‘œλΌλ©΄, console 창에 reject ν•¨μˆ˜λ₯Ό 톡해 λ°›μ•„μ˜¨ 였λ₯˜ λ©”μ‹œμ§€κ°€ λ– μ•Ό ν•œλ‹€.
κ·ΈλŸ¬λ‚˜, νŽ˜μ΄μ§€λ₯Ό μƒˆλ‘œκ³ μΉ¨ ν•œ ν›„ 2μ΄ˆκ°€ μ§€λ‚˜λ©΄, console 창에 μ•„λž˜μ™€ 같은 μ§„μ§œ 였λ₯˜κ°€ λœ¬λ‹€.

Uncaught (in promise) Error: error! πŸ“ => πŸ₯š

μœ„ 였λ₯˜λŠ” promiseμ—μ„œ μ—λŸ¬κ°€ μž‘νžˆμ§€ μ•ŠλŠ”λ‹€λŠ” λœ»μ΄λ‹€.
이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ promiseκ°€ μ„±κ³΅μ μœΌλ‘œ κΈ°λŠ₯을 μˆ˜ν–‰ν–ˆμ„ λ•Œ μ‹€ν–‰λ˜λŠ” then() 말고, promiseκ°€ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” 쀑에 λ¬Έμ œκ°€ λ°œμƒν–ˆμ„ λ•Œ μ‹€ν–‰λ˜λŠ” catch()λ₯Ό 등둝해야 ν•œλ‹€.

getHen()
  .then(hen => getEgg(hen))
  .then(egg => cook(egg))
  .then(meal => console.log(meal))
  .catch(error => console.log(error));
  // getEgg ν•¨μˆ˜μ˜ setTimeout μ•ˆμ˜ reject ν•¨μˆ˜κ°€ μ „λ‹¬ν•˜λŠ” 였λ₯˜ λ©”μ‹œμ§€κ°€ catch()에 μ „λ‹¬λœλ‹€

λΉ„λ‘œμ†Œ console 창에 μ•„λž˜μ™€ 같이, reject ν•¨μˆ˜λ₯Ό 톡해 λ°›μ•„μ˜¨ 였λ₯˜ λ©”μ‹œμ§€κ°€ λœ¨λŠ” 것을 확인할 수 μžˆλ‹€.

Error: error! πŸ“ => πŸ₯š

ν•œνŽΈ, μœ„μ™€ μ•„λž˜μ˜ μ½”λ“œλŠ” κ°™λ‹€.

getHen()
  .then(getEgg)
  .then(cook)
  .then(console.log)
  .catch(console.log);

πŸ’‘ μœ„ μ˜ˆμ œλŠ” getEgg ν•¨μˆ˜μ—μ„œ promiseκ°€ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ‹€κ°€ λ¬Έμ œκ°€ 생겼을 λ•Œ, reject ν•¨μˆ˜λ₯Ό 톡해 λ°›μ•„μ˜¨ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό λ„μ›Œμ£Όκ³ , 더 μ΄μƒμ˜ μ½”λ“œλŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ” κ²½μš°μ΄λ‹€.

ν•œνŽΈ, getEgg ν•¨μˆ˜μ—μ„œ promiseκ°€ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λ‹€κ°€ λ¬Έμ œκ°€ 생겼을 λ•Œ, μ•„μ˜ˆ 였λ₯˜ λ©”μ‹œμ§€λ₯Ό λ‹€λ₯Έ κ°’μœΌλ‘œ λŒ€μ²΄ν•˜κ³ , λκΉŒμ§€ μ½”λ“œκ°€ μ‹€ν–‰λ˜λ„λ‘ ν•  μˆ˜λ„ μžˆλ‹€.

예λ₯Ό λ“€μ–΄, '달걀'을 λ°›μ•„μ˜¬ λ•Œ λ¬Έμ œκ°€ 생길 경우 λ‹€λ₯Έ 재료둜 λŒ€μ²΄ν•˜κ³  μ‹Άλ‹€λ©΄ μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μˆ˜μ •ν•  수 μžˆλ‹€.
then(getEgg) λ°”λ‘œ 밑에 연달아 catch()λ₯Ό 적어 λ°”λ‘œ 문제λ₯Ό ν•΄κ²°ν•˜λ„λ‘ ν•œλ‹€.

getHen()
  .then(getEgg)
  .catch(error => {
    return 'πŸ₯“';
  })
  .then(cook)
  .then(console.log)

// πŸ₯“ => 🍳

6) 콜백 지μ˜₯ νƒˆμΆœν•˜κΈ°

[TIL] 211011 3. 콜백 ν•¨μˆ˜ 3) 콜백 지μ˜₯ μ°Έκ³ 

  • 콜백 지μ˜₯ 예제
class UserStorage {
  loginUser (id, password, onSuccess, onError) {
	setTimeout(() => {
      if (id === 'syong' && password === 'happy' ||
          id === 'corder' && password === 'nice') {
        onSuccess(id);
      } else {
        onError(new Error('not found'));
      }
    }, 2000);
  }
  
  getRoles (user, onSuccess, onError) {
	setTimeout(() => {
      if (user === 'syong') {
        onSuccess({ name: 'syong', role: 'admin' });
      } else {
        onError(new Error('no access'));
      }
    }, 1000);
  }
}

const userStorage = new UserStorage();

const id = prompt('idλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”');
const password = prompt('passwordλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”');

// 콜백 지μ˜₯
userStorage.loginUser(id, password, user => {
  userStorage.getRoles(user, userWithRoles => {
    alert(`${userWithRoles.role} ${userWithRoles.name}λ‹˜, ν™˜μ˜ν•©λ‹ˆλ‹€!`);
  }, error => {
    throw error;
  });
}, error => {
  throw error;
});
  • promiseλ₯Ό μ΄μš©ν•΄ 콜백 지μ˜₯ νƒˆμΆœν•˜κΈ°
class UserStorage {
  loginUser (id, password) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (id === 'syong' && password === 'happy' ||
            id === 'corder' && password === 'nice') {
          resolve(id);
        } else {
          reject(new Error('not found'));
        }
      }, 2000);
    });
  }

  getRoles (user) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (user === 'syong') {
          resolve({ name: 'syong', role: 'admin' });
        } else {
          reject(new Error('no access'));
        }
      }, 1000);
    });
  }
}

const userStorage = new UserStorage();

const id = prompt('idλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”');
const password = prompt('passwordλ₯Ό μž…λ ₯ν•΄μ£Όμ„Έμš”');

userStorage.loginUser(id, password)
  .then(userStorage.getRoles)
  .then(user => alert(`${user.role} ${user.name}λ‹˜, ν™˜μ˜ν•©λ‹ˆλ‹€!`))
  .catch(console.log);

2. async Β· await

  • promiseλ₯Ό λ™κΈ°μ μœΌλ‘œ μ‹€ν–‰λ˜λŠ” κ²ƒμ²˜λŸΌ 보이도둝 λ§Œλ“€μ–΄μ€€λ‹€.

  • promise chaining을 ν•  λ•Œ, κ³„μ†ν•΄μ„œ λ‹€λ₯Έ promise에 μ—°κ²°ν•  경우 μ½”λ“œκ°€ λ‚œμž‘ν•΄μ§ˆ 수 μžˆλ‹€.

    μ΄λ•Œ async와 await을 μ΄μš©ν•˜λ©΄, μ½”λ“œλ₯Ό λ™κΈ°μ‹μœΌλ‘œ 즉, μˆœμ„œλŒ€λ‘œ 보닀 κ°„λ‹¨ν•˜κ³  κ°„νŽΈν•˜κ²Œ μž‘μ„±ν•  수 μžˆλ‹€.

  • 단, 무쑰건 async와 await으둜 λ°”κΏ€ 수 μžˆλŠ” 것은 μ•„λ‹ˆλ‹€. κ·ΈλŒ€λ‘œ promiseλ₯Ό 써야 ν•  λ•Œκ°€ μžˆλ‹€. ν”„λ‘œμ νŠΈλ₯Ό ν•΄λ³΄λ©΄μ„œ 감을 μ½ν˜€μ•Ό ν•œλ‹€.

cf. syntactic sugar(문법적 섀탕)

기쑴에 μ‘΄μž¬ν•˜λŠ” 것 μœ„μ— ν˜Ήμ€ 기쑴에 μ‘΄μž¬ν•˜λŠ” 것을 κ°μ‹Έμ„œ, μ’€ 더 읽기 쉽고 μ΄ν•΄ν•˜κΈ° νŽΈν•˜λ„λ‘ λ§Œλ“œλŠ” 것을 λ§ν•œλ‹€.
ex) async, await, class λ“±


1) async

function fetchUser () {
  // 10μ΄ˆμ— 걸쳐 μ„œλ²„λ‘œλΆ€ν„° 데이터λ₯Ό λ°›μ•„μ˜€λŠ” μ½”λ“œκ°€ μžˆλ‹€κ³  κ°€μ •
  return 'syong'; // μ„œλ²„λ‘œλΆ€ν„° 'syong'μ΄λΌλŠ” 데이터λ₯Ό λ°›μ•„μ˜΄
}

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

// λ‹€λ₯Έ μ½”λ“œ μƒλž΅

πŸ’‘ μœ„μ™€ 같이 λ™κΈ°μ‹μœΌλ‘œ μˆœμ„œλŒ€λ‘œ μž‘μ„±ν•΄μ£Όλ©΄, 이 μ½”λ“œ 뒀에 μž‘μ„±λœ λ‹€λ₯Έ μ½”λ“œλ“€μ€, fetchUser ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜μ–΄ syongμ΄λΌλŠ” 데이터λ₯Ό λ¦¬ν„΄ν•˜κΈ°κΉŒμ§€ 10초 λ™μ•ˆ μ‹€ν–‰λ˜μ§€ λͺ»ν•œλ‹€.

뒀에 μ›Ή νŽ˜μ΄μ§€μ˜ UI κ΄€λ ¨ μ½”λ“œκ°€ μžˆλ‹€λ©΄ μ‚¬μš©μžλŠ” 10초 λ™μ•ˆ 빈 νŽ˜μ΄μ§€λ§Œμ„ 보게 λ˜λŠ” λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. λ”°λΌμ„œ 이λ₯Ό λΉ„λ™κΈ°μ μœΌλ‘œ μˆ˜μ •ν•΄μ€„ ν•„μš”κ°€ μžˆλ‹€.


function fetchUser () {
  return new Promise((resolve, reject) => {
    // 10μ΄ˆμ— 걸쳐 μ„œλ²„λ‘œλΆ€ν„° 데이터λ₯Ό λ°›μ•„μ˜€λŠ” μ½”λ“œ
    return 'syong';
  });
}

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

πŸ’‘ promiseλ₯Ό 생성해 μ½”λ“œλ₯Ό λΉ„λ™κΈ°μ μœΌλ‘œ μˆ˜μ •ν•΄μ£Όμ—ˆλ‹€. 그런데 μœ„μ˜ μ½”λ“œμ—μ„œλŠ” promiseκ°€ μˆ˜ν–‰μ„ μ™„λ£Œν•˜μ—¬ 성곡 ν˜Ήμ€ μ‹€νŒ¨ν–ˆμ„ λ•Œ μ‹€ν–‰λ˜λŠ” resolveλ‚˜ rejectλ₯Ό μž‘μ„±ν•΄μ£Όμ§€ μ•Šμ•˜λ‹€. κ·Έμ € 데이터 'syong'을 return ν•˜λ©΄μ„œ λλ‚œλ‹€.

이 경우, console μ°½μ—λŠ” μ•„λž˜μ™€ 같이 λœ¬λ‹€.

[[PromiseState]]: "pending" // promiseκ°€ μ§€μ •ν•œ 처리λ₯Ό κ³„μ†ν•΄μ„œ μˆ˜ν–‰ 쀑이닀
[[PromiseResult]]: undefined // promiseλŠ” μ„œλ²„λ‘œλΆ€ν„° μ–΄λ–€ 데이터도 받지 μ•Šμ•˜λ‹€.

function fetchUser () {
  return new Promise((resolve, reject) => {
    // 10μ΄ˆμ— 걸쳐 μ„œλ²„λ‘œλΆ€ν„° 데이터λ₯Ό λ°›μ•„μ˜€λŠ” μ½”λ“œ
    resolve('syong');
  });
}

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

πŸ’‘ 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ executor ν•¨μˆ˜ μ•ˆμ—μ„œ resolve ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ„λ‘ μˆ˜μ •ν–ˆλ‹€. 이제 promiseλŠ” κΈ°λŠ₯을 μ •μƒμ μœΌλ‘œ μˆ˜ν–‰ν•œ ν›„ μ΅œμ’… 데이터λ₯Ό μ „λ‹¬ν•˜κ³ μž resolveλ₯Ό ν˜ΈμΆœν•œλ‹€.

이 경우, console μ°½μ—λŠ” μ•„λž˜μ™€ 같이 λœ¬λ‹€.

[[PromiseState]]: "fulfilled" // promiseκ°€ μ§€μ •ν•œ 처리λ₯Ό μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œν–ˆλ‹€
[[PromiseResult]]: "syong" // promise에 syongμ΄λΌλŠ” 데이터λ₯Ό μ „λ‹¬ν•œλ‹€.

async function fetchUser () {
  // 10μ΄ˆμ— 걸쳐 μ„œλ²„λ‘œλΆ€ν„° 데이터λ₯Ό λ°›μ•„μ˜€λŠ” μ½”λ“œ
  return 'syong';
}

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

// λ‹€λ₯Έ μ½”λ“œ μƒλž΅

πŸ’‘ ν•œνŽΈ, ν•¨μˆ˜ μ•žμ— asyncλ₯Ό μΆ”κ°€ν•˜λ©΄ ν•¨μˆ˜μ˜ μ½”λ“œ λΈ”λŸ­μ΄ μžλ™μœΌλ‘œ promise둜 바뀐닀. 이 κ²½μš°μ— μ½”λ“œλ₯Ό λ™κΈ°μ‹μœΌλ‘œ 즉, μˆœμ„œλŒ€λ‘œ μž‘μ„±ν•˜λ”λΌλ„ μ²˜λ¦¬λŠ” λΉ„λ™κΈ°μ μœΌλ‘œ 이뀄진닀.

λ”°λΌμ„œ, promiseκ°€ μ§€μ •λœ 처리λ₯Ό μˆ˜ν–‰ν•˜λŠ” λ™μ•ˆ, 이 μ½”λ“œ 뒀에 μž‘μ„±λœ λ‹€λ₯Έ μ½”λ“œλ“€λ„ promiseκ°€ 처리λ₯Ό μ™„λ£Œλ  λ•ŒκΉŒμ§€ 기닀릴 ν•„μš” 없이, ν•¨κ»˜ μ‹€ν–‰λœλ‹€.


✨ 내일 ν•  것

  1. κ°•μ˜ 계속 λ“£κΈ° (await)
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€