์ฝœ๋ฐฑ ์ง€์˜ฅ(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์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝœ๋ฐฑ ์ง€์˜ฅ์„ ํ”ผํ•˜๊ณ  ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐ์ ์ด๊ณ  ๋ช…๋ฃŒํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.