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

욱이·2020λ…„ 2μ›” 17일
2

πŸ“Œ ν”„λ‘œλ―ΈμŠ€λž€?

  • ν”„λ‘œλ―ΈμŠ€(Promise)λŠ” 비동기 μƒνƒœλ₯Ό κ°’μœΌλ‘œ λ‹€λ£° 수 μžˆλŠ” 객체이닀.
  • ν”„λ‘œλ―ΈμŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ 비동기 ν”„λ‘œκ·Έλž˜λ°μ„ ν•  λ•Œ 동기 ν”„λ‘œκ·Έλž˜λ° λ°©μ‹μœΌλ‘œ μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.

πŸ‘‰ μ½œλ°±νŒ¨ν„΄

  • μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œλŠ” 비동기 ν”„λ‘œκ·Έλž˜λ°μ˜ ν•œ 가지 λ°©μ‹μœΌλ‘œ callback νŒ¨ν„΄μ„ 많이 μ‚¬μš©ν–ˆλ‹€.
  • 콜백 νŒ¨ν„΄μ€ 비동기 μž‘μ—…μ΄ κΈΈμ–΄μ§ˆμˆ˜λ‘ 콜백이 κΉŠμ–΄μ§€κ³ , λ˜ν•œ μ—λŸ¬ 핸듀링 및 디버깅이 μ–΄λ ΅λ‹€.
function callback() {
  asyncFunc1(result => {
    asyncFunc2(result => {
      asyncFunc3(result => {
        asyncFunc4(result => {
          asyncFunc5(result => console.log('success!'), result);
        }, result)
      }, result)
    }, result)
  })
}
             
callback();

πŸ‘‰ ν”„λ‘œλ―ΈμŠ€ νŒ¨ν„΄

  • 콜백의 λ¬Έμ œμ μ„ ν•΄κ²°ν•˜κΈ° μœ„ν•΄ Promise νŒ¨ν„΄μ΄ λ“±μž₯ν–ˆλ‹€.
  • 비동기 μž‘μ—…μ„ 콜백이 μ•„λ‹Œ then 으둜 μ—°κ²°ν•˜κ³ , catch 둜 μ—λŸ¬ 핸듀링 및 디버깅을 νŽΈν•˜κ²Œ ν•  수 μžˆλ‹€.
function promise() {
  asyncFunc1()
    .then(result => asyncFunc2(result))
    .then(result => asyncFunc3(result))
    .then(result => asyncFunc4(result))
    .then(result => asyncFunc5(result))
    .then(result => console.log('success!'))
    .catch(error => console.log('error!'));
}

promise();

🀟 ν”„λ‘œλ―ΈμŠ€μ˜ 3가지 μƒνƒœ

  1. λŒ€κΈ°μ€‘(pending) : κ²°κ³Όλ₯Ό 기닀리고 μžˆλŠ” μƒνƒœ
  2. 이행됨(fulfilled) : μˆ˜ν–‰μ΄ μ •μƒμ μœΌλ‘œ 끝났고 κ²°κ³Ό 값을 κ°–κ³  μžˆλŠ” μƒνƒœ
  3. 거뢀됨(rejected) : μˆ˜ν–‰μ΄ λΉ„μ •μƒμ μœΌλ‘œ λλ‚œ μƒνƒœ
  • 이행됨, 거뢀됨 μƒνƒœλ₯Ό 처리됨(settled) μƒνƒœλΌκ³  λΆ€λ₯Έλ‹€.
  • ν”„λ‘œλ―ΈμŠ€κ°€ 처리됨(settled) μƒνƒœκ°€ 되면 더이상 λ‹€λ₯Έ μƒνƒœλ‘œ λ³€κ²½λ˜μ§€ μ•ŠλŠ”λ‹€.
  • promiseλŠ” new ν‚€μ›Œλ“œλ₯Ό 톡해 ν”„λ‘œλ―ΈμŠ€λ₯Ό μƒμ„±ν•œλ‹€.
new Promise(resolve, reject);

πŸ”‘ resolve, reject

  • λΉ„λ™κΈ°λ‘œ μž‘μ—…μ„ μˆ˜ν–‰ ν›„ μ„±κ³΅ν–ˆμ„ λ•Œ resolve λ₯Ό ν˜ΈμΆœν•˜κ³  μ‹€νŒ¨ν–ˆμ„ λ•Œ reject λ₯Ό 호좜 ν•œλ‹€.
  • reject λ₯Ό ν˜ΈμΆœν•˜λ©΄ 거뢀됨(rejected) μƒνƒœκ°€ 되고, λ˜ν•œ ν•¨μˆ˜ μ•ˆμ—μ„œ μ˜ˆμ™Έ(exception) κ°€ λ°œμƒν•˜λ©΄ 거뢀됨(rejected) μƒνƒœκ°€ λœλ‹€.
function promise(data) {
  return new Promise((resolve, reject) => {
    return !data ? resject('rejected promise!') : resolve(data);
  })
}

promise();

πŸ”‘ finally

  • finally λ©”μ„œλ“œλŠ” 비동기 μž‘μ—… μˆ˜ν–‰ ν›„ 성곡 μ‹€νŒ¨ 여뢀와 상관없이 λ§ˆμ§€λ§‰μ— ν˜ΈμΆœλ˜λŠ” λ©”μ„œλ“œμ΄λ‹€.
function promise() {
  return new Promise((resolve, result) => {
    // ...
  })
}

promise()
  .then(result => console.log('success!'))
  .catch(error => console.log(error))
  .finally(() => console.log('finished!'));

πŸ”‘ Promise.all

  • Promise.all 은 μ—¬λŸ¬ 개의 ν”„λ‘œλ―ΈμŠ€λ₯Ό λ³‘λ ¬λ‘œ μ²˜λ¦¬ν•  λ•Œ μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
  • Promise.all ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λŠ” μž…λ ₯된 λͺ¨λ“  ν”„λ‘œλ―ΈμŠ€κ°€ 처리됨(settled) μƒνƒœκ°€ λ˜μ–΄μ•Ό λ§ˆμ°¬κ°€μ§€λ‘œ 처리됨 μƒνƒœκ°€ λœλ‹€.
  • λ§Œμ•½ ν•˜λ‚˜λΌλ„ 거뢀됨(rejected) μƒνƒœκ°€ λœλ‹€λ©΄ Promise.all ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λ„ 거뢀됨(rejected) μƒνƒœκ°€ λœλ‹€.
function promise1() {
  return new Promise((resolve, result) => {
    // ...
  })
}

function promise2() {
  return new Promise((resolve, result) => {
    // ...
  })
}

Promise.all([promise1(), promise2()])
  .then(result => console.log('result : ', result)) // result : ['result1', 'result2']
  .catch(error => console.log('error!'));

πŸ”‘ Promise.race

  • Promise.race μ—¬λŸ¬ 개의 ν”„λ‘œλ―ΈμŠ€ μ€‘μ—μ„œ κ°€μž₯ 빨리 처리된 ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μ΄λ‹€.
  • Promise.race ν•¨μˆ˜μ— μž…λ ₯된 μ—¬λŸ¬ ν”„λ‘œλ―ΈμŠ€ μ€‘μ—μ„œ ν•˜λ‚˜λΌλ„ 처리됨 μƒνƒœκ°€ 되면, Promise.race ν•¨μˆ˜κ°€ λ°˜ν™˜ν•˜λŠ” ν”„λ‘œλ―ΈμŠ€λ„ 처리됨 μƒνƒœκ°€ λœλ‹€.
  • promise1() ν•¨μˆ˜κ°€ 3μ΄ˆμ•ˆμ— 데이터λ₯Ό λ°›μœΌλ©΄ then λ©”μ„œλ“œκ°€ 호좜되고, 그렇지 μ•ŠμœΌλ©΄ catch λ©”μ„œλ“œκ°€ ν˜ΈμΆœλœλ‹€.
function promise1() {
  return new Promise((resolve, result) => {
    setTimeout(() => resolve('success!'), 1000);
  });
}

function promise2() {
  return new Promise((resolve, reject) => setTimeout(reject, 3000));
}

Promise.race([promise1(), promise2()])
  .then(result => console.log('result : ', result))
  .catch(error => console.log('error!'));

πŸ“Œ async await

  • ν”„λ‘œλ―ΈμŠ€λŠ” 객체둜 μ‘΄μž¬ν•˜μ§€λ§Œ async await λŠ” ν•¨μˆ˜μ— μ μš©λ˜λŠ” κ°œλ…μ΄λ‹€.

πŸ”‘ async

  • async ν‚€μ›Œλ“œλ₯Ό μ΄μš©ν•΄μ„œ μ •μ˜λœ ν•¨μˆ˜λŠ” async await ν•¨μˆ˜μ΄λ©°, 항상 ν”„λ‘œλ―ΈμŠ€λ₯Ό λ°˜ν™˜ν•œλ‹€.
  • ν”„λ‘œλ―ΈμŠ€μ˜ then λ©”μ„œλ“œμ™€ λ§ˆμ°¬κ°€μ§€λ‘œ async await ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ λ°˜ν™˜ν•˜λŠ” 값이 ν”„λ‘œλ―ΈμŠ€λΌλ©΄ κ·Έ 객체λ₯Ό κ·ΈλŒ€λ‘œ λ°˜ν™˜ν•œλ‹€.
  • ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ˜ˆμ™Έκ°€ λ°œμƒν•˜λŠ” κ²½μš°μ—λŠ” 거뢀됨(rejected) μƒνƒœμΈ ν”„λ‘œλ―ΈμŠ€κ°€ λ°˜ν™˜ λœλ‹€.
async function promise(data) {
  if(!data) throw new Error('error!');
  return Promise.resolve('success!');
}

promise()
  .then(result => console.log(result))
  .catch(error => console.log(error))

πŸ”‘ await

  • await ν‚€μ›Œλ“œλŠ” async await ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©λœλ‹€.
  • await ν‚€μ›Œλ“œ 였λ₯Έμͺ½μ— ν”„λ‘œλ―ΈμŠ€λ₯Ό μž…λ ₯ν•˜λ©΄ κ·Έ ν”„λ‘œλ―ΈμŠ€κ°€ 처리됨(settled) μƒνƒœκ°€ 될 λ•ŒκΉŒμ§€ κΈ°λ‹€λ¦°λ‹€.
  • λ”°λΌμ„œ await ν‚€μ›Œλ“œλ‘œ 비동기 처리λ₯Ό κΈ°λ‹€λ¦¬λ©΄μ„œ 순차적으둜 동기식 μ½”λ“œλ₯Ό μž‘μ„±ν•  수 μžˆλ‹€.
function promise() {
  return new Promise((resolve, result) => {
    // ...
  })
}

async function asyncFunc() {
  const { data } = await promise({ data: { result: 'success!' } });
  console.log('result : ', data); // result : { result: 'success!' }
}

asyncFunc();

πŸ”‘ async await ν™œμš©ν•˜μ—¬ 비동기 ν•¨μˆ˜λ₯Ό λ³‘λ ¬λ‘œ μ‹€ν–‰ν•˜λŠ” 방법

  • λ‘κ°œμ˜ ν”„λ‘œλ―ΈμŠ€λ₯Ό λ¨Όμ € μƒμ„±ν•˜κ³  await ν‚€μ›Œλ“œλ₯Ό λ‚˜μ€‘μ— μ‚¬μš©ν•˜λ©΄ λ³‘λ ¬λ‘œ μ‹€ν–‰λ˜λŠ” μ½”λ“œκ°€ λœλ‹€.
  • Promise.all 을 μ‚¬μš©ν•˜λ©΄ 더 κ°„λ‹¨ν•˜κ²Œ λ³‘λ ¬λ‘œ μ‹€ν–‰ν•  수 μžˆλ‹€.
function promise1() {
  return new Promise((resolve, result) => {
    // ...
  })
}

function promise2() {
  return new Promise((resolve, result) => {
    // ...
  })
}

async function asyncFunc() {
  const prom1 = promise1();
  const prom2 = promise2();
  
  const data1 = await prom1;
  const data2 = await prom2;
  
  // Promise.all
  const [data3, data4] = Promise.all([prom1, prom2]);
}

asyncFunc();

πŸ”‘ async await μ˜ˆμ™Έ 처리

  • async await ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ λ°œμƒν•˜λŠ” μ˜ˆμ™ΈλŠ” try/catch 문으둜 μ²˜λ¦¬ν•˜λŠ”κ²Œ μ’‹λ‹€.
  • 비동기 ν•¨μˆ˜μ™€ 동기 ν•¨μˆ˜μ—μ„œ λ°œμƒν•˜λŠ” λͺ¨λ“  μ˜ˆμ™Έκ°€ catch λ¬Έμ—μ„œ μ²˜λ¦¬λœλ‹€.
  • λ§Œμ•½ asyncFunc ν•¨μˆ˜κ°€ async await ν•¨μˆ˜κ°€ μ•„λ‹ˆμ˜€λ‹€λ©΄ doAsync() ν•¨μˆ˜μ—μ„œ λ°œμƒν•˜λŠ” μ˜ˆμ™ΈλŠ” ν•¨μˆ˜μ˜ μ²˜λ¦¬κ°€ λλ‚˜λŠ” μ‹œμ μ„ μ•Œ 수 μ—†κΈ° λ•Œλ¬Έμ— catch λ¬Έμ—μ„œ μ²˜λ¦¬λ˜μ§€ μ•ŠλŠ”λ‹€.
function doAsync() {
  return new Promise((resolve, result) => {
    // ...
  })
}

function doSync() {
  // ...
}

async function asyncFunc() {
  try {
    await doAsync();
    return doSync();
  } catch (error) {
    console.log('error', error);
  }
}

asyncFunc();

πŸ”‘ Thenable

  • Thenable 은 ν”„λ‘œλ―ΈμŠ€ 처럼 λ™μž‘ν•˜λŠ” 객체이닀.
  • async awaitλŠ” ν”„λ‘œλ―ΈμŠ€κ°€ μ•„λ‹ˆλ”λΌλ„ then λ©”μ„œλ“œλ₯Ό 가진 객체λ₯Ό ν”„λ‘œλ―ΈμŠ€μ²˜λŸΌ μ·¨κΈ‰ν•œλ‹€.
  1. ThenableClassλŠ” then λ©”μ„œλ“œλ₯Ό 가지고 μžˆμœΌλ―€λ‘œ ThenableClass둜 μƒμ„±λœ κ°μ²΄λŠ” Thenable이닀.
  2. async await ν•¨μˆ˜λŠ” Thenable도 ν”„λ‘œλ―ΈμŠ€ 처럼 μ²˜λ¦¬ν•œλ‹€.
class ThenableClass {
  then(resolve, reject) { // 1.
    setTimeout(() => resolve('success!'), 1000);
  }
}

async function asyncFunc() {
  const result = await new ThenableClass(); // 2.
  console.log(result); // success!
}
profile
πŸ“·

0개의 λŒ“κΈ€