콜백 μ§€μ˜₯(Callback Hell)κ³Ό ν”„λ‘œλ―ΈμŠ€(Promise)

콜백 μ§€μ˜₯(Callback Hell)은 비동기 ν”„λ‘œκ·Έλž˜λ°μ—μ„œ 자주 λ°œμƒν•˜λŠ” μ½”λ“œ ꡬ쑰의 ν•œ μ’…λ₯˜λ‘œ, μ—¬λŸ¬ 비동기 λ™μž‘μ΄ μ€‘μ²©λœ ν˜•νƒœλ‘œ μ½”λ“œκ°€ μž‘μ„±λ  λ•Œ λ°œμƒν•˜λŠ” 가독성 μ €ν•˜μ™€ μœ μ§€λ³΄μˆ˜μ˜ 어렀움을 μ§€μΉ­ν•©λ‹ˆλ‹€. 주둜 콜백 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” μƒν™©μ—μ„œ 비동기적인 μž‘μ—…λ“€μ΄ μ€‘μ²©λ˜μ–΄ λ°œμƒν•˜λ©°, μ½”λ“œκ°€ κΈΈμ–΄μ§ˆμˆ˜λ‘ 가독성이 λ–¨μ–΄μ§€κ³  둜직의 이해가 μ–΄λ €μ›Œμ§€λŠ” λ¬Έμ œκ°€ λ°œμƒν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, μ„œλ²„μ—μ„œ 데이터λ₯Ό λ°›μ•„μ˜€κ³ , κ·Έ 데이터λ₯Ό κ°€κ³΅ν•œ ν›„ λ‹€μ‹œ μ„œλ²„μ— μ „μ†‘ν•˜κ³ , κ·Έ 응닡을 λ°›μ•„μ™€μ„œ 화면에 좜λ ₯ν•˜λŠ” 일련의 비동기 λ™μž‘λ“€μ΄ μ€‘μ²©λ˜λŠ” μƒν™©μ—μ„œ 콜백 μ§€μ˜₯이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ μ€‘μ²©λœ 콜백 ν•¨μˆ˜λ“€μ€ μ½”λ“œμ˜ λ“€μ—¬μ“°κΈ° μˆ˜μ€€μ΄ κΉŠμ–΄μ§€κ³ , 가독성이 λ–¨μ–΄μ Έ μ½”λ“œλ₯Ό μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§‘λ‹ˆλ‹€.
asyncFunction1(function(result1) {
    asyncFunction2(result1, function(result2) {
        asyncFunction3(result2, function(result3) {
            // ...
        });
    });
});
μ΄λŸ¬ν•œ μ€‘μ²©λœ κ΅¬μ‘°λŠ” 비동기 λ™μž‘μ΄ λ§Žμ•„μ§ˆμˆ˜λ‘ μ½”λ“œλ₯Ό μ΄ν•΄ν•˜κΈ° μ–΄λ €μ›Œμ§€λ©°, μ—λŸ¬ 처리 및 μœ μ§€λ³΄μˆ˜κ°€ λ³΅μž‘ν•΄μ§‘λ‹ˆλ‹€.

콜백 μ§€μ˜₯을 ν•΄κ²°ν•˜κΈ° μœ„ν•œ λ°©λ²•μœΌλ‘œλŠ” Promiseλ‚˜ Async/Await와 같은 비동기 처리 방식을 ν™œμš©ν•˜λŠ” 것이 μžˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 μ½”λ“œμ˜ 가독성을 ν–₯μƒμ‹œν‚€κ³ , 비동기 λ™μž‘λ“€μ„ 보닀 λͺ…μ‹œμ μ΄κ³  κ΄€λ¦¬ν•˜κΈ° μ‰¬μš΄ ν˜•νƒœλ‘œ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Promiseλ‚˜ Async/Await을 μ‚¬μš©ν•˜μ—¬ μ½œλ°±μ§€μ˜₯을 ν•΄κ²°ν•˜λŠ” 방법

콜백 μ§€μ˜₯을 ν•΄κ²°ν•˜κΈ° μœ„ν•΄ Promiseλ‚˜ Async/Await을 μ‚¬μš©ν•˜λŠ” 것은 비동기 μ½”λ“œλ₯Ό 더 κ°„κ²°ν•˜κ³  가독성 있게 λ§Œλ“€ 수 μžˆλŠ” 방법 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. μ•„λž˜λŠ” 각각 Promise와 Async/Await을 μ‚¬μš©ν•˜μ—¬ 콜백 μ§€μ˜₯을 ν•΄κ²°ν•˜λŠ” 예제 μ½”λ“œμž…λ‹ˆλ‹€.

πŸ“ 1. Promise μ‚¬μš©

function asyncFunction1() {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 1');
              resolve('Result from Async Function 1');
          }, 1000);
      });
  }
  
  function asyncFunction2(result) {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 2');
              resolve('Result from Async Function 2');
          }, 1000);
      });
  }
  
  function asyncFunction3(result) {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 3');
              resolve('Result from Async Function 3');
          }, 1000);
      });
  }
  
  asyncFunction1()
      .then((result1) => asyncFunction2(result1))
      .then((result2) => asyncFunction3(result2))
      .then((result3) => {
          console.log('Final Result:', result3);
      })
      .catch((error) => {
          console.error('Error:', error);
      });
      

πŸ“ Async/Await μ‚¬μš©

function asyncFunction1() {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 1');
              resolve('Result from Async Function 1');
          }, 1000);
      });
  }
  
  function asyncFunction2(result) {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 2');
              resolve('Result from Async Function 2');
          }, 1000);
      });
  }
  
  function asyncFunction3(result) {
      return new Promise((resolve) => {
          // 비동기 μž‘μ—… μˆ˜ν–‰
          setTimeout(() => {
              console.log('Async Function 3');
              resolve('Result from Async Function 3');
          }, 1000);
      });
  }
  
  async function runAsyncFunctions() {
      try {
          const result1 = await asyncFunction1();
          const result2 = await asyncFunction2(result1);
          const result3 = await asyncFunction3(result2);
  
          console.log('Final Result:', result3);
      } catch (error) {
          console.error('Error:', error);
      }
  }
  
  runAsyncFunctions();
      
μœ„μ˜ μ½”λ“œμ—μ„œλŠ” 각각의 비동기 ν•¨μˆ˜κ°€ Promiseλ₯Ό λ°˜ν™˜ν•˜λ„λ‘ μž‘μ„±λ˜μ—ˆκ³ , 이λ₯Ό 순차적으둜 ν˜ΈμΆœν•˜λ„λ‘ then λ˜λŠ” await을 μ‚¬μš©ν•˜μ˜€μŠ΅λ‹ˆλ‹€. async & awaitμ—μ„œ μ˜ˆμ™Έλ₯Ό μ²˜λ¦¬ν•˜λŠ” 방법은 λ°”λ‘œ try catchμž…λ‹ˆλ‹€.

μ½”λ“œμ—μ„œ λ°œμƒν•œ λ„€νŠΈμ›Œν¬ 톡신 였λ₯˜λΏλ§Œ μ•„λ‹ˆλΌ κ°„λ‹¨ν•œ νƒ€μž… 였λ₯˜ λ“±μ˜ 일반적인 였λ₯˜κΉŒμ§€λ„ catch둜 μž‘μ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€. 발견된 μ—λŸ¬λŠ” error 객체에 λ‹΄κΈ°κΈ° λ•Œλ¬Έμ— μ—λŸ¬μ˜ μœ ν˜•μ— 맞게 μ—λŸ¬ μ½”λ“œλ₯Ό μ²˜λ¦¬ν•΄μ£Όμ‹œλ©΄ λ©λ‹ˆλ‹€.

ν”„λ‘œλ―ΈμŠ€λ₯Ό μ‚¬μš©ν•˜κ²Œ 되면 ν”„λ‘œλ―ΈμŠ€ 객체에 비동기 처리된 결과값이 μ €μž₯되며 콜백의 경우 맀번 비동기 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ—¬ λΉ„λ™κΈ°μ²˜λ¦¬λœ 결과값을 μ–»μ—ˆλ‹€λ©΄ ν”„λ‘œλ―ΈμŠ€λŠ” .then λ©”μ†Œλ“œλ₯Ό ν†΅ν•΄μ„œ μ›ν•˜λŠ” λ•Œμ— μ €μž₯λ˜μ–΄ μžˆλŠ” 비동기 값을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Async & Await을 μ‚¬μš©ν•˜λ©΄ 비동기 μ½”λ“œλ₯Ό 동기 μ½”λ“œμ²˜λŸΌ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이둜써 μ½”λ“œμ˜ μ˜λ„κ°€ λͺ…ν™•ν•΄μ§€κ³  가독성이 ν–₯μƒλ©λ‹ˆλ‹€. Async & Await을 μ‚¬μš©ν•˜λ©΄ 콜백 μ§€μ˜₯을 ν”Όν•˜κ³  비동기 μ½”λ“œλ₯Ό ꡬ쑰적이고 λͺ…λ£Œν•˜κ²Œ μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.