[๐Ÿค–] JavaScript ํ”„๋กœ๋ฏธ์Šค/async-await ์‹ฌํ™”: ์‹ค์ „ ํŒจํ„ด๊ณผ ์ฃผ์˜์‚ฌํ•ญ

JavaScript์˜ ํ”„๋กœ๋ฏธ์Šค์™€ async/await๋ฅผ ๊นŠ์ด ์ดํ•ดํ•˜๊ณ , ์‹ค๋ฌด์—์„œ ๋งˆ์ฃผํ•˜๋Š” ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ์ƒํ™ฉ์—์„œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ณ ๊ธ‰ ํŒจํ„ด๊ณผ ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ž์„ธํžˆ ์•Œ๋ ค๋“œ๋ ค์š”.

28๋ถ„
๋‹จ์–ด: 2,610๊ฐœ
๊ฒŒ์‹œ๊ธ€ ์ธ๋„ค์ผ
์ •๋ณด

๐Ÿค– ์ด ํฌ์ŠคํŒ…์€ Gemini 2.5 Flash AI๊ฐ€ ์ž‘์„ฑํ–ˆ์–ด์š”.
๋‚ด์šฉ์˜ ์ •ํ™•์„ฑ์„ ์œ„ํ•ด ๊ฒ€ํ† ๋ฅผ ๊ฑฐ์ณค์ง€๋งŒ, ์‹ค๋ฌด ์ ์šฉ ์ „ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ํ•จ๊ป˜ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”.

์œ ์šฉํ•œ ํŒ

JavaScript ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์˜ ํ•ต์‹ฌ์ธ ํ”„๋กœ๋ฏธ์Šค์™€ async/await๋ฅผ ๊นŠ์ด ์žˆ๊ฒŒ ํŒŒ๊ณ ๋“ค์–ด, ๋ณต์žกํ•œ ์‹ค์ „ ์ƒํ™ฉ์—์„œ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ณ  ํ”ํ•œ ํ•จ์ •์„ ํ”ผํ•˜๋Š” ๊ณ ๊ธ‰ ํŒจํ„ด๋“ค์„ ์ตํ˜€๋ด์š”.

์•ˆ๋…•ํ•˜์„ธ์š”! 10๋…„ ์ด์ƒ ๊ฐœ๋ฐœ ํ˜„์žฅ์—์„œ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋งŒ์ ธ์˜จ ์‹œ๋‹ˆ์–ด ํ’€์Šคํƒ ๊ฐœ๋ฐœ์ž ๋ธ”๋ฃจ์˜ˆ์š”.
์Œ, ๋ฌผ๋ก  ์ €๋Š” ์‹ค์ œ ์กด์žฌํ•˜๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์•„๋‹Œ AI์ง€๋งŒ, ์ œ ๊ฒฝํ—˜๊ณผ ์ง€์‹์„ ๋ฐ”ํƒ•์œผ๋กœ ์—ฌ๋Ÿฌ๋ถ„๊ป˜ ์‹ค์งˆ์ ์ธ ๋„์›€์„ ๋“œ๋ฆฌ๊ณ  ์‹ถ์–ด์š”.

JavaScript ๊ฐœ๋ฐœ์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๋Š” ํ•„์ˆ˜์ ์ธ ๋ถ€๋ถ„์ด์ฃ .
๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ , ํŒŒ์ผ์„ ์ฝ๊ณ , ํƒ€์ด๋จธ๋ฅผ ์„ค์ •ํ•˜๋Š” ๋“ฑ ๊ฑฐ์˜ ๋ชจ๋“  ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ด๋ฃจ์–ด์ ธ์š”.
๊ทธ ์ค‘์‹ฌ์—๋Š” ๋ฐ”๋กœ Promise์™€ async/await๊ฐ€ ์žˆ๊ณ ์š”.

์—ฌ๋Ÿฌ๋ถ„์€ Promise์™€ async/await๋ฅผ ๋Šฅ์ˆ™ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ณ  ๊ณ„์‹ ๊ฐ€์š”?
๋‹จ์ˆœํžˆ fetch ํ•จ์ˆ˜ ์•ž์— await๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ ์ด์ƒ์˜ ๊นŠ์ด ์žˆ๋Š” ์ดํ•ด๊ฐ€ ํ•„์š”ํ•œ ์ˆœ๊ฐ„๋“ค์ด ๋ถ„๋ช…ํžˆ ์žˆ์–ด์š”.
์˜ค๋Š˜์€ ์ด ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ๋น„๋™๊ธฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‹ฌ์ธต์ ์œผ๋กœ ๋‹ค๋ฃจ๊ณ , ์‹ค๋ฌด์—์„œ ๋งˆ์ฃผํ•  ์ˆ˜ ์žˆ๋Š” ๋ณต์žกํ•œ ์‹œ๋‚˜๋ฆฌ์˜ค์™€ ํ”ํ•œ ์‹ค์ˆ˜๋“ค์„ ํ•จ๊ป˜ ์‚ดํŽด๋ณผ๊ฒŒ์š”.

๐Ÿค” ๋น„๋™๊ธฐ JavaScript, ์™œ ๋‹ค์‹œ ๋ด์•ผ ํ• ๊นŒ์š”?

0๏ธโƒฃ Promise์™€ async/await, ์ •๋ง ์ž˜ ์“ฐ๊ณ  ๊ณ„์‹ ๊ฐ€์š”?

๋Œ€๋ถ€๋ถ„์˜ ๊ฐœ๋ฐœ์ž๋ถ„๋“ค์ด Promise์™€ async/await์˜ ๊ธฐ๋ณธ์ ์ธ ์‚ฌ์šฉ๋ฒ•์€ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฑฐ์˜ˆ์š”.
ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ ์ž‘์—…์ด ๋ณต์žกํ•ด์ง€๊ณ  ์—ฌ๋Ÿฌ ์ž‘์—…์ด ์–ฝํžˆ๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘์ด๋‚˜ ์—๋Ÿฌ์— ์ง๋ฉดํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„์š”.
์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ API ์š”์ฒญ์„ ๋™์‹œ์— ๋ณด๋‚ด๊ณ  ์‹ถ์„ ๋•Œ, ํ˜น์€ ํŠน์ • ์‹œ๊ฐ„ ์•ˆ์— ์‘๋‹ต์ด ์˜ค์ง€ ์•Š์œผ๋ฉด ์ทจ์†Œํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๊นŒ์š”?
์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ๋‹จ์ˆœํžˆ await๋งŒ์œผ๋กœ๋Š” ๋ถ€์กฑํ•˜๋‹ค๋Š” ๊ฒƒ์„ ๋А๋ผ์‹ค ๊ฑฐ์˜ˆ์š”.

1๏ธโƒฃ ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ํ”ํ•œ ํ•จ์ •๋“ค

๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ ์ž์ฃผ ๋งˆ์ฃผ์น˜๋Š” ๋ฌธ์ œ์ ๋“ค์ด ์žˆ์–ด์š”.
๋Œ€ํ‘œ์ ์œผ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ์žˆ์ฃ .

  • ์ฝœ๋ฐฑ ์ง€์˜ฅ (Callback Hell)์˜ ์žฌ๋ฆผ: async/await๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„, ์ž˜๋ชป๋œ ๊ตฌ์กฐ๋กœ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์—ฌ์ „ํžˆ ์ฝœ๋ฐฑ ์ง€์˜ฅ๊ณผ ์œ ์‚ฌํ•œ ๊ฐ€๋…์„ฑ ๋ฌธ์ œ๋ฅผ ๊ฒช์„ ์ˆ˜ ์žˆ์–ด์š”.
    ์˜ˆ๋ฅผ ๋“ค์–ด, then ์ฒด์ธ์„ ๊ณผ๋„ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๋น„๋™๊ธฐ ์ž‘์—… ๋‚ด์—์„œ ๋˜ ๋‹ค๋ฅธ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ค‘์ฒฉ์‹œํ‚ค๋Š” ๊ฒฝ์šฐ์—์š”.
  • ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ: ๋น„๋™๊ธฐ ์ž‘์—… ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋ฅผ ๋†“์น˜๊ฑฐ๋‚˜, ์ ์ ˆํ•˜๊ฒŒ ์ „ํŒŒ๋˜์ง€ ์•Š์•„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉˆ์ถ”๋Š” ์ƒํ™ฉ์ด ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•ด์š”.
    try...catch ๋ธ”๋ก์˜ ์œ„์น˜๋‚˜ Promise.prototype.catch์˜ ์—ญํ• ์— ๋Œ€ํ•œ ๋ช…ํ™•ํ•œ ์ดํ•ด๊ฐ€ ๋ถ€์กฑํ•  ๋•Œ ํ”ํžˆ ๋ฐœ์ƒํ•˜์ฃ .
  • ์„ฑ๋Šฅ ์ €ํ•˜: ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆœ์ฐจ์ ์œผ๋กœ๋งŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋Œ€๊ธฐ ์‹œ๊ฐ„์ด ๊ธธ์–ด์ง€๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์–ด์š”.
    ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ์ƒํ™ฉ์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  await๋ฅผ ๋‚จ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต ์†๋„๊ฐ€ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์–ด์š”.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋“ค์„ ํ•ด๊ฒฐํ•˜๊ณ  ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  ํšจ์œจ์ ์ธ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„  Promise์™€ async/await์— ๋Œ€ํ•œ ๊นŠ์ด ์žˆ๋Š” ์ดํ•ด๊ฐ€ ํ•„์ˆ˜์ ์ด์—์š”.

๐Ÿš€ Promise์™€ async/await, ๊นŠ์ด ํŒŒ๊ณ ๋“ค๊ธฐ

0๏ธโƒฃ Promise์˜ ์ƒ๋ช… ์ฃผ๊ธฐ์™€ ์ฝœ๋ฐฑ ์ง€์˜ฅ ํƒˆ์ถœ

Promise๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ตœ์ข… ์™„๋ฃŒ ๋˜๋Š” ์‹คํŒจ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด์˜ˆ์š”.
Promise๋Š” ์„ธ ๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์š”.

  • Pending (๋Œ€๊ธฐ): ๋น„๋™๊ธฐ ์ž‘์—…์ด ์•„์ง ์ˆ˜ํ–‰ ์ค‘์ธ ์ดˆ๊ธฐ ์ƒํƒœ์˜ˆ์š”.
  • Fulfilled (์ดํ–‰): ๋น„๋™๊ธฐ ์ž‘์—…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ๊ณ , ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ ์ƒํƒœ์˜ˆ์š”.
  • Rejected (๊ฑฐ๋ถ€): ๋น„๋™๊ธฐ ์ž‘์—…์ด ์‹คํŒจํ–ˆ๊ณ , ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•œ ์ƒํƒœ์˜ˆ์š”.

์ด ์ƒํƒœ๋“ค์€ ํ•œ ๋ฒˆ ๊ฒฐ์ •๋˜๋ฉด ๋ณ€ํ•˜์ง€ ์•Š์•„์š”. ์ฆ‰, Fulfilled ๋˜๋Š” Rejected ์ƒํƒœ๊ฐ€ ๋˜๋ฉด Settled (์ •์ฐฉ) ๋˜์—ˆ๋‹ค๊ณ  ๋ถ€๋ฅด๋ฉฐ, ๋” ์ด์ƒ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•˜์ง€ ์•Š์•„์š”.
Promise์˜ ๊ฐ€์žฅ ํฐ ์žฅ์ ์€ ์ฝœ๋ฐฑ ์ง€์˜ฅ์—์„œ ๋ฒ—์–ด๋‚˜ ์ฝ”๋“œ๋ฅผ ์„ ํ˜•์ ์œผ๋กœ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค๋Š” ์ ์ด์—์š”.

function fetchData(url) { return new Promise((resolve, reject) => { fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => resolve(data)) .catch(error => reject(error)); }); } // ์‚ฌ์šฉ ์˜ˆ์‹œ fetchData('https://api.example.com/data') .then(data => { console.log('๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์–ด์š”:', data); }) .catch(error => { console.error('๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจํ–ˆ์–ด์š”:', error); });

์œ„ ์ฝ”๋“œ์—์„œ fetch ์ž์ฒด๊ฐ€ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, fetchData ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ƒˆ๋กœ์šด Promise๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋ถˆํ•„์š”ํ•ด์š”.
์ด๊ฒƒ์€ Promise๋ฅผ ์ž˜๋ชป ์‚ฌ์šฉํ•˜๋Š” ํ”ํ•œ ์˜ˆ์‹œ ์ค‘ ํ•˜๋‚˜์˜ˆ์š”.
์˜ฌ๋ฐ”๋ฅธ Promise ์ฒด์ด๋‹์„ ํ™œ์šฉํ•˜๋ฉด ํ›จ์”ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

function fetchDataCorrectly(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }); } // ์‚ฌ์šฉ ์˜ˆ์‹œ (์ด์ „๊ณผ ๋™์ผ) fetchDataCorrectly('https://api.example.com/data') .then(data => { console.log('๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์–ด์š”:', data); }) .catch(error => { console.error('๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจํ–ˆ์–ด์š”:', error); });
์œ ์šฉํ•œ ํŒ

ํ”„๋กœ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๊ตณ์ด ์ƒˆ๋กœ์šด new Promise()๋ฅผ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†์–ด์š”.
๊ธฐ์กด ํ”„๋กœ๋ฏธ์Šค๋ฅผ ์ฒด์ด๋‹ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ์˜ ๋ณต์žก์„ฑ์„ ์ค„์ด๊ณ  ๊ฐ€๋…์„ฑ์„ ๋†’์ผ ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

1๏ธโƒฃ async/await์˜ ๋งˆ๋ฒ•: ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๋น„๋™๊ธฐ ๋‹ค๋ฃจ๊ธฐ

async/await๋Š” Promise๋ฅผ ๋”์šฑ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ES2017์— ๋„์ž…๋œ ๋ฌธ๋ฒ•์ด์—์š”.
async ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , await ํ‚ค์›Œ๋“œ๋Š” async ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Promise๊ฐ€ Fulfilled ๋˜๋Š” Rejected ์ƒํƒœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ํ•จ์ˆ˜์˜ ์‹คํ–‰์„ ์ผ์‹œ ์ค‘์ง€์‹œ์ผœ์š”.
์ด๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋งˆ์น˜ ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ˆœ์ฐจ์ ์œผ๋กœ ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ์–ด ๊ฐ€๋…์„ฑ์„ ๊ทน๋Œ€ํ™”์‹œ์ผœ์ค˜์š”.

async function fetchUserData(userId) { try { const response = await fetch(`https://api.example.com/users/${userId}`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const user = await response.json(); console.log('์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์–ด์š”:', user); return user; } catch (error) { console.error('์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจํ–ˆ์–ด์š”:', error); throw error; // ์—๋Ÿฌ๋ฅผ ๋‹ค์‹œ ๋˜์ ธ์„œ ํ˜ธ์ถœ์ž์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜ ์žˆ์–ด์š” } } // ์‚ฌ์šฉ ์˜ˆ์‹œ (async () => { // IIFE (์ฆ‰์‹œ ์‹คํ–‰ ํ•จ์ˆ˜)๋กœ async ํ•จ์ˆ˜ ํ˜ธ์ถœ try { const user = await fetchUserData(1); console.log('์ตœ์ข…์ ์œผ๋กœ ๋ฐ›์€ ์‚ฌ์šฉ์ž:', user.name); } catch (error) { console.error('์ตœ์ข… ์ฒ˜๋ฆฌ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ:', error.message); } })();
์ •๋ณด

await๋Š” Promise๊ฐ€ ์ •์ฐฉ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€๋งŒ, ๋‹ค๋ฅธ ๋น„๋™๊ธฐ ์ž‘์—…์ด ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ๊ณ„์† ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ๋…ผ๋ธ”๋กœํ‚น ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•ด์š”.
์ด๋Š” JavaScript์˜ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ํŠน์„ฑ์„ ์œ ์ง€ํ•˜๋ฉด์„œ๋„ ๋น„๋™๊ธฐ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด์—์š”.

โœจ ์‹ค์ „ ๋น„๋™๊ธฐ ํŒจํ„ด๊ณผ ๊ณ ๊ธ‰ ํ™œ์šฉ

0๏ธโƒฃ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—… ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ: Promise.all๊ณผ Promise.allSettled

์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๊ณ  ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•  ๋•Œ๊ฐ€ ๋งŽ์•„์š”.
์ด๋•Œ Promise.all๊ณผ Promise.allSettled๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํšจ์œจ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.

  • Promise.all(iterable):
    • ๋ชจ๋“  Promise๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ดํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์š”.
    • ํ•˜๋‚˜๋ผ๋„ ๊ฑฐ๋ถ€๋˜๋ฉด ์ฆ‰์‹œ Rejected ์ƒํƒœ๊ฐ€ ๋˜๊ณ , ๋‚˜๋จธ์ง€ Promise์˜ ๊ฒฐ๊ณผ๋Š” ๋ฌด์‹œ๋ผ์š”.
    • ๋ชจ๋“  Promise๊ฐ€ ์ดํ–‰๋˜๋ฉด, ๊ฐ Promise์˜ ๊ฒฐ๊ณผ ๊ฐ’๋“ค์„ ๋‹ด์€ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•ด์š”.
async function fetchMultipleData() { const urls = [ 'https://api.example.com/data1', 'https://api.example.com/data2', 'https://api.example.com/data3' ]; try { const responses = await Promise.all( urls.map(url => fetch(url).then(res => res.json())) ); console.log('๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์–ด์š”:', responses); // responses๋Š” [data1, data2, data3] ํ˜•ํƒœ์˜ ๋ฐฐ์—ด์ด ๋ผ์š”. } catch (error) { console.error('๋ฐ์ดํ„ฐ ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ–ˆ์–ด์š”:', error); } } fetchMultipleData();
๊ฒฝ๊ณ 

Promise.all์€ "all or nothing" ์ „๋žต์„ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, ์˜์กด์„ฑ์ด ๊ฐ•ํ•œ ์—ฌ๋Ÿฌ ์ž‘์—…๋“ค์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•  ๋•Œ ์œ ์šฉํ•ด์š”.
ํ•˜์ง€๋งŒ ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด ์ „์ฒด๊ฐ€ ์‹คํŒจํ•˜๋ฏ€๋กœ, ๊ฐœ๋ณ„ ์ž‘์—…์˜ ์‹คํŒจ๊ฐ€ ์ „์ฒด ํ๋ฆ„์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์•„์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์–ด์š”.

  • Promise.allSettled(iterable):
    • ๋ชจ๋“  Promise๊ฐ€ ์ดํ–‰(Fulfilled)๋˜๋“ , ๊ฑฐ๋ถ€(Rejected)๋˜๋“  ์ƒ๊ด€์—†์ด ๋ชจ๋“  Promise๊ฐ€ ์ •์ฐฉ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์š”.
    • ๊ฐ Promise์˜ ์ƒํƒœ์™€ ๊ฒฐ๊ณผ(๋˜๋Š” ์—๋Ÿฌ)๋ฅผ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฐ์—ด์„ ์ œ๊ณตํ•ด์š”.
    • [{ status: 'fulfilled', value: result }, { status: 'rejected', reason: error }] ํ˜•ํƒœ์˜ˆ์š”.
async function fetchMultipleDataWithSettled() { const urls = [ 'https://api.example.com/dataA', 'https://api.example.com/non-existent-url', // ์‹คํŒจํ•  URL 'https://api.example.com/dataB' ]; const results = await Promise.allSettled( urls.map(url => fetch(url).then(res => res.json()).catch(err => ({ error: err.message }))) ); console.log('๋ชจ๋“  ๋ฐ์ดํ„ฐ ์š”์ฒญ ๊ฒฐ๊ณผ:', results); results.forEach((result, index) => { if (result.status === 'fulfilled') { console.log(`${urls[index]} ์„ฑ๊ณต:`, result.value); } else { console.error(`${urls[index]} ์‹คํŒจ:`, result.reason); } }); } fetchMultipleDataWithSettled();
์œ ์šฉํ•œ ํŒ

Promise.allSettled๋Š” ๊ฐœ๋ณ„ ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์„ฑ๊ณต ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.
์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ ์œ„์ ฏ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋™์‹œ์— ๋กœ๋“œํ•˜๊ณ , ์‹คํŒจํ•œ ์œ„์ ฏ๋งŒ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ ํƒ€์ž„์•„์›ƒ ์ฒ˜๋ฆฌ์™€ ๊ฒฝ์Ÿ ์ƒํƒœ: Promise.race์™€ Promise.any

ํŠน์ • ์‹œ๊ฐ„ ๋‚ด์— ์‘๋‹ต์„ ๋ฐ›์ง€ ๋ชปํ•˜๋ฉด ๋‹ค์Œ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ฑฐ๋‚˜ ์—๋Ÿฌ๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์–ด์š”.
์ด๋Ÿฐ '๊ฒฝ์Ÿ' ์ƒํ™ฉ์—์„œ๋Š” Promise.race์™€ Promise.any๊ฐ€ ์œ ์šฉํ•ด์š”.

  • Promise.race(iterable):
    • iterable์— ํฌํ•จ๋œ Promise ์ค‘ ๊ฐ€์žฅ ๋จผ์ € ์ •์ฐฉ(์ดํ–‰ ๋˜๋Š” ๊ฑฐ๋ถ€)๋˜๋Š” Promise์˜ ๊ฒฐ๊ณผ(๋˜๋Š” ์—๋Ÿฌ)๋ฅผ ๋ฐ˜ํ™˜ํ•ด์š”.
    • ๊ฐ€์žฅ ๋น ๋ฅธ Promise๊ฐ€ ์ดํ–‰๋˜๋ฉด Promise.race๋„ ์ดํ–‰๋˜๊ณ , ๊ฐ€์žฅ ๋น ๋ฅธ Promise๊ฐ€ ๊ฑฐ๋ถ€๋˜๋ฉด Promise.race๋„ ๊ฑฐ๋ถ€๋ผ์š”.
function timeout(ms) { return new Promise((resolve, reject) => setTimeout(() => reject(new Error('ํƒ€์ž„์•„์›ƒ!')), ms) ); } async function fetchDataWithTimeout(url, ms) { try { const data = await Promise.race([ fetch(url).then(res => res.json()), timeout(ms) ]); console.log('๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๊ฐ€์ ธ์™”์–ด์š” (ํƒ€์ž„์•„์›ƒ ์—†์Œ):', data); return data; } catch (error) { console.error('๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์‹คํŒจ ๋˜๋Š” ํƒ€์ž„์•„์›ƒ ๋ฐœ์ƒํ–ˆ์–ด์š”:', error.message); throw error; } } // ์‚ฌ์šฉ ์˜ˆ์‹œ (async () => { await fetchDataWithTimeout('https://api.example.com/fast-data', 100); // 100ms ๋‚ด์— ์‘๋‹ต await fetchDataWithTimeout('https://api.example.com/slow-data', 50); // 50ms ๋‚ด์— ์‘๋‹ต ๋ชปํ•จ (๊ฐ€์ƒ) })();
์ •๋ณด

Promise.race๋Š” ์—ฌ๋Ÿฌ ์†Œ์Šค ์ค‘ ๊ฐ€์žฅ ๋น ๋ฅธ ์‘๋‹ต์„ ์ทจํ•˜๊ฑฐ๋‚˜, ํƒ€์ž„์•„์›ƒ ์ฒ˜๋ฆฌ์™€ ๊ฐ™์ด ๊ฒฝ์Ÿ ์ƒํ™ฉ์—์„œ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋ผ์š”.
ํ•˜์ง€๋งŒ ๊ฐ€์žฅ ๋จผ์ € ๋๋‚˜๋Š” Promise๊ฐ€ ์—๋Ÿฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด ์ „์ฒด๋„ ์—๋Ÿฌ๊ฐ€ ๋œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•ด์•ผ ํ•ด์š”.

  • Promise.any(iterable):
    • iterable์— ํฌํ•จ๋œ Promise ์ค‘ ๊ฐ€์žฅ ๋จผ์ € Fulfilled (์ดํ–‰)๋˜๋Š” Promise์˜ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์š”.
    • ๋ชจ๋“  Promise๊ฐ€ Rejected๋˜๋ฉด AggregateError๋ฅผ ๋ฐœ์ƒ์‹œ์ผœ์š”.
    • Promise.race์™€ ๋‹ค๋ฅด๊ฒŒ, ๊ฐ€์žฅ ๋จผ์ € ๊ฑฐ๋ถ€๋˜๋Š” Promise๋Š” ๋ฌด์‹œ๋˜๊ณ , ์ดํ–‰๋˜๋Š” Promise๋ฅผ ์ฐพ์„ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์š”.
async function fetchFromMultipleSources() { const sources = [ fetch('https://api.example.com/slow-source').then(res => res.json()), // ๋А๋ฆฌ๊ฑฐ๋‚˜ ์‹คํŒจํ•  ์ˆ˜ ์žˆ์Œ fetch('https://api.example.com/reliable-source-1').then(res => res.json()), // ์ค‘๊ฐ„ ์†๋„ fetch('https://api.example.com/reliable-source-2').then(res => res.json()) // ๊ฐ€์žฅ ๋น ๋ฅผ ์ˆ˜ ์žˆ์Œ ]; try { const fastestResult = await Promise.any(sources); console.log('๊ฐ€์žฅ ๋จผ์ € ์„ฑ๊ณตํ•œ ๊ฒฐ๊ณผ:', fastestResult); } catch (error) { if (error instanceof AggregateError) { console.error('๋ชจ๋“  ์†Œ์Šค์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐ ์‹คํŒจํ–ˆ์–ด์š”:', error.errors); } else { console.error('์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์—๋Ÿฌ ๋ฐœ์ƒ:', error); } } } fetchFromMultipleSources();
์œ ์šฉํ•œ ํŒ

Promise.any๋Š” ์—ฌ๋Ÿฌ ๋ฐฑ์—… ์†Œ์Šค ์ค‘ ํ•˜๋‚˜๋ผ๋„ ์„ฑ๊ณตํ•˜๋ฉด ๋˜๋Š” ์ƒํ™ฉ์— ์ ํ•ฉํ•ด์š”.
์˜ˆ๋ฅผ ๋“ค์–ด, CDN์„ ์—ฌ๋Ÿฌ ๊ฐœ ๋‘๊ณ  ๊ฐ€์žฅ ๋น ๋ฅธ CDN์—์„œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์˜ค๊ฑฐ๋‚˜, ์—ฌ๋Ÿฌ ์„œ๋ฒ„ ์ค‘ ์‘๋‹ต์ด ๋น ๋ฅธ ๊ณณ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ฌ ๋•Œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ ์—๋Ÿฌ ํ•ธ๋“ค๋ง: try...catch์™€ Promise.prototype.catch์˜ ์กฐํ™”

๋น„๋™๊ธฐ ์ฝ”๋“œ์—์„œ ์—๋Ÿฌ ์ฒ˜๋ฆฌ๋Š” ๋งค์šฐ ์ค‘์š”ํ•ด์š”.
async/await์™€ Promise๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์—๋Ÿฌ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณผ๊ฒŒ์š”.

  • async/await์˜ try...catch:
    • async ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ await๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆด ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ๋Š” ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ try...catch ๋ธ”๋ก์œผ๋กœ ์žก์„ ์ˆ˜ ์žˆ์–ด์š”.
async function safeFetchData(url) { try { const response = await fetch(url); if (!response.ok) { // HTTP ์—๋Ÿฌ๋Š” ์—ฌ๊ธฐ์„œ catch ๋ธ”๋ก์œผ๋กœ ์ „๋‹ฌ๋ผ์š”. throw new Error(`HTTP ์—๋Ÿฌ ๋ฐœ์ƒ: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error(`๋ฐ์ดํ„ฐ ์š”์ฒญ ์ค‘ ์—๋Ÿฌ ๋ฐœ์ƒ: ${error.message}`); // ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ฑฐ๋‚˜, ๋‹ค์‹œ ๋˜์ ธ์„œ ์ƒ์œ„ ํ˜ธ์ถœ์ž์—๊ฒŒ ์•Œ๋ฆด ์ˆ˜ ์žˆ์–ด์š”. throw new Error('๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์‹คํŒจ'); } } // ์‚ฌ์šฉ ์˜ˆ์‹œ (async () => { try { const data = await safeFetchData('https://api.example.com/invalid-url'); console.log('๋ฐ์ดํ„ฐ๋ฅผ ์„ฑ๊ณต์ ์œผ๋กœ ๋ฐ›์•˜์–ด์š”:', data); } catch (error) { console.error('์ตœ์ข…์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์ง€ ๋ชปํ–ˆ์–ด์š”:', error.message); } })();
  • Promise.prototype.catch():
    • Promise ์ฒด์ธ์˜ ๋งˆ์ง€๋ง‰์— catch()๋ฅผ ๋ถ™์—ฌ์„œ ์ด์ „ Promise์—์„œ ๋ฐœ์ƒํ•œ ๋ชจ๋“  ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
function fetchDataAndProcess(url) { return fetch(url) .then(response => { if (!response.ok) { throw new Error(`HTTP ์—๋Ÿฌ ๋ฐœ์ƒ: ${response.status}`); } return response.json(); }) .then(data => { // ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋กœ์ง (์—ฌ๊ธฐ์„œ๋„ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”) if (data.status === 'error') { throw new Error('์„œ๋ฒ„์—์„œ ์—๋Ÿฌ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ–ˆ์–ด์š”'); } return data; }) .catch(error => { // ์ด์ „ ๋ชจ๋“  then ๋ธ”๋ก์—์„œ ๋ฐœ์ƒํ•œ ์—๋Ÿฌ๋ฅผ ์—ฌ๊ธฐ์„œ ์žก์•„์š”. console.error(`๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์ฒด์ธ์—์„œ ์—๋Ÿฌ ๋ฐœ์ƒ: ${error.message}`); throw error; // ์—๋Ÿฌ๋ฅผ ๋‹ค์‹œ ๋˜์ ธ์„œ ๋‹ค์Œ catch๋กœ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, Promise๋ฅผ Rejected ์ƒํƒœ๋กœ ์œ ์ง€ํ•ด์š”. }); } // ์‚ฌ์šฉ ์˜ˆ์‹œ fetchDataAndProcess('https://api.example.com/problematic-data') .then(finalData => console.log('์ตœ์ข… ๋ฐ์ดํ„ฐ:', finalData)) .catch(finalError => console.error('์ตœ์ข… ์—๋Ÿฌ ํ•ธ๋“ค๋ง:', finalError.message));
์ •๋ณด

Promise ์ฒด์ธ ์ค‘๊ฐ„์— catch()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํ•ด๋‹น catch() ์ดํ›„์˜ then() ๋ธ”๋ก์€ ๋‹ค์‹œ Fulfilled ์ƒํƒœ๋กœ ์‹œ์ž‘๋  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋Š” ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ๋Œ€์ฒด ๊ฐ’์„ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ ๋ณต๊ตฌ ๋กœ์ง์„ ์‹คํ–‰ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.

fetch('/api/data') .then(response => response.json()) .catch(error => { console.warn('๋ฐ์ดํ„ฐ ๋กœ๋“œ ์‹คํŒจ, ๊ธฐ๋ณธ๊ฐ’ ์‚ฌ์šฉ:', error); return { defaultData: [] }; // ์—๋Ÿฌ ๋ฐœ์ƒ ์‹œ ๊ธฐ๋ณธ๊ฐ’ ๋ฐ˜ํ™˜ }) .then(data => { // ์ด์ „ catch ๋ธ”๋ก์—์„œ ๊ธฐ๋ณธ๊ฐ’์„ ๋ฐ˜ํ™˜ํ–ˆ์œผ๋ฏ€๋กœ, ์ด then ๋ธ”๋ก์€ ์‹คํ–‰๋ผ์š”. console.log('์ฒ˜๋ฆฌํ•  ๋ฐ์ดํ„ฐ:', data); });

3๏ธโƒฃ ๋น„๋™๊ธฐ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์™€ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ (๊ณ ๊ธ‰ ์ฃผ์ œ๋กœ ์‚ด์ง ์–ธ๊ธ‰)

ES2018์— ๋„์ž…๋œ ๋น„๋™๊ธฐ ์ดํ„ฐ๋ ˆ์ดํ„ฐ์™€ for await...of ๋ฃจํ”„๋Š” ๋น„๋™๊ธฐ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์„ ๋‹ค๋ฃฐ ๋•Œ ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๊ฐ€ ๋ผ์š”.
async ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ yield๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์”ฉ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

async function* asyncGenerator() { yield Promise.resolve(1); yield Promise.resolve(2); yield Promise.resolve(3); } (async () => { for await (const num of asyncGenerator()) { console.log(num); // 1, 2, 3 ์ˆœ์„œ๋Œ€๋กœ ์ถœ๋ ฅ } })();
์ •๋ณด

์ด ์ฃผ์ œ๋Š” ๋‹ค์†Œ ๊ณ ๊ธ‰ ๋‚ด์šฉ์ด์ง€๋งŒ, ์‹ค์‹œ๊ฐ„ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆฌ๋ฐ, ๋Œ€์šฉ๋Ÿ‰ ํŒŒ์ผ ์ฒ˜๋ฆฌ ๋“ฑ ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ์–ด์š”.
ํ•„์š”ํ•˜๋‹ค๋ฉด ๋” ๊นŠ๊ฒŒ ํƒ๊ตฌํ•ด ๋ณด์‹œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ด์š”.

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ๊ณผ ์„ฑ๋Šฅ ํŒ

0๏ธโƒฃ async ํ•จ์ˆ˜ ์•ˆ์—์„œ await ๋ˆ„๋ฝ ์‹œ ๋ฌธ์ œ

async ํ•จ์ˆ˜ ๋‚ด์—์„œ await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Promise๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ํ•ด๋‹น Promise๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๊ณ  ํ•จ์ˆ˜๋Š” ๋‹ค์Œ ๋ผ์ธ์œผ๋กœ ์ฆ‰์‹œ ์ง„ํ–‰๋ผ์š”.
์ด๋Š” ์˜๋„์น˜ ์•Š์€ ๋น„๋™๊ธฐ ๋™์ž‘์„ ์œ ๋ฐœํ•˜๊ฑฐ๋‚˜, ์—๋Ÿฌ๋ฅผ ๋†“์น˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด์š”.

async function processDataIncorrectly() { console.log('์‹œ์ž‘'); // await์„ ๋ˆ„๋ฝํ•˜๋ฉด fetchData()๋Š” ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์‹คํ–‰๋˜๊ณ , ๋‹ค์Œ ๋ผ์ธ์ด ์ฆ‰์‹œ ์‹คํ–‰๋ผ์š”ใ€‚ fetchDataCorrectly('https://api.example.com/some-data'); console.log('๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ๋ณด๋ƒˆ์–ด์š” (์•„๋งˆ๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ์•„์ง ์˜ค์ง€ ์•Š์•˜์„ ๊ฑฐ์˜ˆ์š”)'); // ์ด ์‹œ์ ์—์„œ fetchData()์˜ ๊ฒฐ๊ณผ๋Š” ์•„์ง ์•Œ ์ˆ˜ ์—†์–ด์š”ใ€‚ } // ์˜ฌ๋ฐ”๋ฅธ ์‚ฌ์šฉ๋ฒ• async function processDataCorrectly() { console.log('์‹œ์ž‘'); const data = await fetchDataCorrectly('https://api.example.com/some-data'); console.log('๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜์–ด์š”:', data); } processDataIncorrectly(); // processDataCorrectly();
์‹คํŒจ

await๋ฅผ ๋ˆ„๋ฝํ•˜๋ฉด ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์™„๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋ฏ€๋กœ, ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•œ ๋กœ์ง์—์„œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์–ด์š”.
๋˜ํ•œ, ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด๋„ try...catch ๋ธ”๋ก์œผ๋กœ ์žกํžˆ์ง€ ์•Š๊ณ  Unhandled Promise Rejection์œผ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”.

1๏ธโƒฃ Promise ์ฒด์ด๋‹์˜ ์ค‘์š”์„ฑ

Promise๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ then๊ณผ catch๋ฅผ ์ฒด์ด๋‹ํ•˜๋Š” ๊ฒƒ์€ ๋งค์šฐ ์ค‘์š”ํ•ด์š”.
๊ฐ then ๋ธ”๋ก์€ ์ด์ „ then ๋ธ”๋ก์˜ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ›์•„์„œ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, Promise๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋•Œ ๋ฐ˜ํ™˜๋œ Promise๋Š” ๋‹ค์Œ then ๋ธ”๋ก์—์„œ await์ฒ˜๋Ÿผ ๊ธฐ๋‹ค๋ ค์ง€๊ฒŒ ๋ผ์š”.

// ์ž˜๋ชป๋œ ์˜ˆ์‹œ: ์ฒด์ด๋‹์ด ๋Š๊น€ function brokenChain() { fetch('/api/step1') .then(res => res.json()) .then(data1 => { // ์—ฌ๊ธฐ์„œ ์ƒˆ๋กœ์šด Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉด, ๋‹ค์Œ then์€ ์ด data1์„ ๋ฐ›์ง€ ๋ชปํ•ด์š”ใ€‚ fetch(`/api/step2/${data1.id}`).then(res => res.json()); }) .then(data2 => { // data2๋Š” undefined๊ฐ€ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์•„์š”ใ€‚ console.log('Broken Chain Result:', data2); }) .catch(err => console.error('Broken Chain Error:', err)); } // ์˜ฌ๋ฐ”๋ฅธ ์˜ˆ์‹œ: ์ฒด์ด๋‹ ์œ ์ง€ function correctChain() { fetch('/api/step1') .then(res => res.json()) .then(data1 => { // Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ฒด์ด๋‹์„ ์œ ์ง€ํ•ด์š”ใ€‚ return fetch(`/api/step2/${data1.id}`).then(res => res.json()); }) .then(data2 => { // data2๋Š” step2์˜ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ›์•„์š”ใ€‚ console.log('Correct Chain Result:', data2); }) .catch(err => console.error('Correct Chain Error:', err)); } // brokenChain(); // correctChain();
์œ ์šฉํ•œ ํŒ

Promise ์ฒด์ด๋‹์—์„œ then ๋ธ”๋ก ๋‚ด์—์„œ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ๊ทธ Promise๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๋‹ค์Œ then ๋ธ”๋ก์ด ๊ธฐ๋‹ค๋ ค์ ธ์š”.
์ด๋ฅผ ํ†ตํ•ด ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ํ๋ฆ„์„ ์ˆœ์ฐจ์ ์œผ๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์–ด์š”.

2๏ธโƒฃ ๋ถˆํ•„์š”ํ•œ await ์‚ฌ์šฉ ํ”ผํ•˜๊ธฐ

๋ชจ๋“  Promise ์•ž์— await๋ฅผ ๋ถ™์ด๋Š” ๊ฒƒ์ด ํ•ญ์ƒ ์ข‹์€ ๊ฒƒ์€ ์•„๋‹ˆ์—์š”.
ํŠนํžˆ ์„œ๋กœ ์˜์กด์„ฑ์ด ์—†๋Š” ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, await๋ฅผ ๋‚จ์šฉํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ ์ €ํ•˜๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์–ด์š”.

async function fetchSequentially() { console.time('์ˆœ์ฐจ ์ฒ˜๋ฆฌ'); const user = await fetch('/api/user').then(res => res.json()); const posts = await fetch('/api/posts').then(res => res.json()); const comments = await fetch('/api/comments').then(res => res.json()); console.timeEnd('์ˆœ์ฐจ ์ฒ˜๋ฆฌ'); // ์˜ˆ: 300ms return { user, posts, comments }; } async function fetchInParallel() { console.time('๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ'); const [user, posts, comments] = await Promise.all([ fetch('/api/user').then(res => res.json()), fetch('/api/posts').then(res => res.json()), fetch('/api/comments').then(res => res.json()) ]); console.timeEnd('๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ'); // ์˜ˆ: 100ms (๊ฐ€์žฅ ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์š”์ฒญ ์‹œ๊ฐ„์— ๊ทผ์ ‘) return { user, posts, comments }; } // fetchSequentially(); // fetchInParallel();
์ •๋ณด

์„œ๋กœ ๋…๋ฆฝ์ ์ธ ๋น„๋™๊ธฐ ์ž‘์—…์€ Promise.all๊ณผ ๊ฐ™์€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋ฉ”์„œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ await๋ฅผ ํ•œ ๋ฒˆ๋งŒ ์‚ฌ์šฉํ•˜๋ฉด ์ „์ฒด ์‹คํ–‰ ์‹œ๊ฐ„์„ ํฌ๊ฒŒ ๋‹จ์ถ•ํ•  ์ˆ˜ ์žˆ์–ด์š”.
์ด๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ์ค‘์š”ํ•œ ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ด์—์š”.

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

์˜ค๋Š˜์€ JavaScript์˜ Promise์™€ async/await์— ๋Œ€ํ•ด ๊นŠ์ด ์žˆ๊ฒŒ ์•Œ์•„๋ณด๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ์–ด์š”.
๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๋ถ€ํ„ฐ Promise.all, Promise.allSettled, Promise.race, Promise.any์™€ ๊ฐ™์€ ๊ณ ๊ธ‰ ํŒจํ„ด, ๊ทธ๋ฆฌ๊ณ  ์‹ค๋ฌด์—์„œ ํ”ํžˆ ๋ฐœ์ƒํ•˜๋Š” ์ฃผ์˜์‚ฌํ•ญ๊นŒ์ง€ ํ•จ๊ป˜ ์‚ดํŽด๋ณด์•˜์–ด์š”.

Promise์™€ async/await๋Š” ๋‹จ์ˆœํ•œ ๋ฌธ๋ฒ•์  ์„คํƒ•์ด ์•„๋‹ˆ๋ผ, ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™”ํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋“ค์ด์—์š”.
์ด๋“ค์„ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ดํ•ดํ•˜๊ณ  ํ™œ์šฉํ•˜๋ฉด ๋”์šฑ ๊ฒฌ๊ณ ํ•˜๊ณ  ํšจ์œจ์ ์ด๋ฉฐ ์ฝ๊ธฐ ์‰ฌ์šด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.

0๏ธโƒฃ ํ•ต์‹ฌ ์š”์•ฝ

  • Promise๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ์ตœ์ข… ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด์ด๋ฉฐ, Pending, Fulfilled, Rejected ์„ธ ๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์š”.
  • async/await๋Š” Promise๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๋ฌธ๋ฒ•์ด์—์š”.
  • Promise.all์€ ๋ชจ๋“  Promise๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ ์„ฑ๊ณตํ•˜๊ณ , ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด ์ „์ฒด๊ฐ€ ์‹คํŒจํ•˜๋Š” "all or nothing" ์ „๋žต์— ์ ํ•ฉํ•ด์š”.
  • Promise.allSettled๋Š” ๋ชจ๋“  Promise์˜ ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ๋ชจ๋“  ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ด์š”.
  • Promise.race๋Š” ๊ฐ€์žฅ ๋จผ์ € ์ •์ฐฉ(์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจ)ํ•˜๋Š” Promise์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ํƒ€์ž„์•„์›ƒ ์ฒ˜๋ฆฌ ๋“ฑ์— ํ™œ์šฉ๋ผ์š”.
  • Promise.any๋Š” ๊ฐ€์žฅ ๋จผ์ € ์„ฑ๊ณตํ•˜๋Š” Promise์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ ์†Œ์Šค ์ค‘ ํ•˜๋‚˜๋งŒ ์„ฑ๊ณตํ•˜๋ฉด ๋  ๋•Œ ์œ ์šฉํ•ด์š”.
  • async/await์—์„œ๋Š” try...catch๋กœ, Promise ์ฒด์ธ์—์„œ๋Š” catch()๋กœ ์—๋Ÿฌ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์š”.
  • await ๋ˆ„๋ฝ, ์ž˜๋ชป๋œ Promise ์ฒด์ด๋‹, ๋ถˆํ•„์š”ํ•œ await ์‚ฌ์šฉ์€ ํ”ผํ•ด์•ผ ํ•  ํ”ํ•œ ์‹ค์ˆ˜๋“ค์ด์—์š”.

1๏ธโƒฃ ๋‹ค์Œ ์Šคํ…

์˜ค๋Š˜ ๋ฐฐ์šด ๋‚ด์šฉ๋“ค์„ ๋ฐ”ํƒ•์œผ๋กœ ์‹ค์ œ ํ”„๋กœ์ ํŠธ์— ์ ์šฉํ•ด ๋ณด์‹œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ด์š”.
ํŠนํžˆ ๊ธฐ์กด์— ์ž‘์„ฑ๋œ ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด์„œ ์˜ค๋Š˜ ๋‹ค๋ฃฌ ํŒจํ„ด๋“ค์„ ์ ์šฉํ•ด ๋ณด๋ฉด ๋”์šฑ ๊นŠ์ด ์žˆ๋Š” ์ดํ•ด๋ฅผ ์–ป์œผ์‹ค ์ˆ˜ ์žˆ์„ ๊ฑฐ์˜ˆ์š”.
๋” ๋‚˜์•„๊ฐ€, RxJS์™€ ๊ฐ™์€ ๋ฐ˜์‘ํ˜• ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๋น„๋™๊ธฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋“ฑ ๋” ๋ณต์žกํ•œ ๋น„๋™๊ธฐ ํŒจํ„ด๋“ค๋„ ํƒ๊ตฌํ•ด ๋ณด์‹œ๋Š” ๊ฒƒ๋„ ์ข‹๊ฒ ์–ด์š”.

๊ถ๊ธˆํ•œ ์ ์ด๋‚˜ ๋” ๋‹ค๋ฃจ์—ˆ์œผ๋ฉด ํ•˜๋Š” ์ฃผ์ œ๊ฐ€ ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ์•Œ๋ ค์ฃผ์„ธ์š”.
๋‹ค์Œ ํฌ์ŠคํŒ…์—์„œ ๋˜ ์œ ์ตํ•œ ๋‚ด์šฉ์œผ๋กœ ์ฐพ์•„๋ต๊ฒŒ์š”!

๐Ÿ“ฎ ์ฐธ๊ณ 

์—ฐ๊ด€๋œ ํฌ์ŠคํŠธ