** ๐Ÿ“Œ๋น„๋™๊ธฐ๋ž€ ๋ฌด์—‡์ธ๊ฐ€?**

๋น„๋™๊ธฐ โ†’ โ€œ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋‹ค์Œ ์ž‘์—…์œผ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๋ฐฉ์‹โ€


๐ŸŽฏ ๋™๊ธฐ vs ๋น„๋™๊ธฐ ๋น„๊ต

์œ ํ˜• ๋™๊ธฐ ๋น„๋™๊ธฐ
ํŠน์ง• ์ž‘์—… ์™„๋ฃŒ ํ›„ ๋‹ค์Œ ์ง„ํ–‰ ์ž‘์—… ์™„๋ฃŒ ์—ฌ๋ถ€ ๊ด€๊ณ„์—†์ด ์ง„ํ–‰
์˜ˆ์‹œ alert(), prompt() setTimeout(), fetch()
์žฅ์  ์ˆœ์ฐจ์ , ์˜ˆ์ธก ๊ฐ€๋Šฅ UI ๋ฉˆ์ถค ๋ฐฉ์ง€, ํšจ์œจ์ 
๋‹จ์  ๋А๋ฆผ, ๋ธ”๋กœํ‚น ๋ฐœ์ƒ ๋ณต์žกํ•œ ์ œ์–ด, ์ฝœ๋ฐฑ ํ—ฌ ๊ฐ€๋Šฅ

๐Ÿงฉ ๊ธฐ๋ณธ ์˜ˆ์‹œ

// ๋™๊ธฐ
console.log('A');
console.log('B');

// ๋น„๋™๊ธฐ
console.log('A');
setTimeout(() => console.log('B'), 1000);
console.log('C');

2๏ธโƒฃ ๐Ÿงต ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ & ์ด๋ฒคํŠธ ๋ฃจํ”„

๐Ÿ“Œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŠน์ง•


๐Ÿš€ Event Loop ๋„์‹ํ™”

[ Call Stack ] <---> [ Event Loop ] <---> [ Callback Queue ]
        โ†‘                                         โ†“
   ์‹คํ–‰ ์ค‘์ธ ํ•จ์ˆ˜                              ์™„๋ฃŒ๋œ ๋น„๋™๊ธฐ ํ•จ์ˆ˜

๐Ÿง  ๋ฉด์ ‘ ํฌ์ธํŠธ

โ€œJS๊ฐ€ ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ์ธ๋ฐ, ์–ด๋–ป๊ฒŒ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ?โ€

โ†’ Web API + Event Loop + Callback Queue ๊ตฌ์กฐ ๋•๋ถ„!


3๏ธโƒฃ ๐Ÿ”„ Callback (์ฝœ๋ฐฑ)

๐Ÿ“Œ ์ •์˜:

๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ธ์ž๋กœ ์ „๋‹ฌ๋˜๋Š” ํ•จ์ˆ˜ โ†’ ํŠน์ • ์ž‘์—… ์™„๋ฃŒ ํ›„ ์‹คํ–‰


โœ… ๊ธฐ์ดˆ ์˜ˆ์ œ

function greet(name, callback) {
  console.log(`Hello, ${name}`);
  callback();
}

greet('Tom', () => console.log('Welcome!'));

4๏ธโƒฃ ๐Ÿšจ Callback Hell ์‹ฌํ™”

๐Ÿ“Œ ๋ฌธ์ œ์ 


โŒ ์ฝœ๋ฐฑ ํ—ฌ ์˜ˆ์‹œ

setTimeout(() => {
  console.log('1');
  setTimeout(() => {
    console.log('2');
    setTimeout(() => {
      console.log('3');
    }, 1000);
  }, 1000);
}, 1000);

5๏ธโƒฃ โœจ Promise ๊ตฌ์กฐ & ๋™์ž‘ ์›๋ฆฌ

๐Ÿ“Œ ์ •์˜

๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๊ฐ’(์„ฑ๊ณต/์‹คํŒจ)์„ ํ‘œํ˜„ํ•˜๋Š” ๊ฐ์ฒด


๐Ÿ“Š ์ƒํƒœ ๋ณ€ํ™”

์ƒํƒœ ์„ค๋ช…
Pending ๋Œ€๊ธฐ ์ƒํƒœ
Fulfilled ์„ฑ๊ณต(resolve)
Rejected ์‹คํŒจ(reject)

โœ… ๊ธฐ๋ณธ ์˜ˆ์ œ

const myPromise = new Promise((resolve, reject) => {
  let success = true;
  if(success) resolve('Success!');
  else reject('Error!');
});

myPromise
  .then(result => console.log(result))  // ์„ฑ๊ณต
  .catch(error => console.log(error))   // ์‹คํŒจ
  .finally(() => console.log('Done!')); // ํ•ญ์ƒ ์‹คํ–‰

๐Ÿงฉ Promise Chaining (์—ฐ์‡„ ์ฒ˜๋ฆฌ)

fetch('url1')
  .then(res => res.json())
  .then(data => fetch('url2'))
  .then(res => res.json())
  .then(data2 => console.log('Complete'))
  .catch(err => console.error(err));

6๏ธโƒฃ ๐Ÿ”ฅ Promise ์‹ฌํ™” ํŒจํ„ด

๐Ÿš€ Promise.all

Promise.all([
  fetch('url1'),
  fetch('url2')
]).then(([res1, res2]) => console.log('All done!'));

โšก Promise.race

Promise.race([
  fetch('url1'),
  fetch('url2')
]).then(res => console.log('First done!'));

โœ… Promise.allSettled

Promise.allSettled([
  Promise.resolve('A'),
  Promise.reject('B')
]).then(results => console.log(results));

๐ŸŒŸ Promise.any

Promise.any([
  Promise.reject('X'),
  Promise.resolve('Y')
]).then(result => console.log(result)); // Y

7๏ธโƒฃ ๐ŸŸข async/await ๋‚ด๋ถ€ ์ž‘๋™ ์›๋ฆฌ & ์‹ฌํ™”

๐Ÿ“Œ ์ •์˜

Promise๋ฅผ ๋” ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ์“ฐ๊ธฐ ์œ„ํ•œ ๋ฌธ๋ฒ• โ†’ ๋™๊ธฐ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋‚ด๋ถ€๋Š” ๋น„๋™๊ธฐ


โœ… ๊ธฐ๋ณธ ์˜ˆ์ œ

async function fetchData() {
  try {
    const res = await fetch('url');
    const data = await res.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  } finally {
    console.log('Done');
  }
}
fetchData();

๐Ÿš€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์ตœ์ ํ™”: Promise.all ํ™œ์šฉ

async function parallelFetch() {
  const [res1, res2] = await Promise.all([
    fetch('url1'),
    fetch('url2')
  ]);
  const data1 = await res1.json();
  const data2 = await res2.json();
}

๐Ÿšจ ์ฃผ์˜: forEach + async/await ๊ธˆ์ง€

[1,2,3].forEach(async (num) => {
  await fetchData(num); // ์ œ๋Œ€๋กœ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Œ
});

โœ… ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•: forโ€ฆof

for (const num of [1,2,3]) {
  await fetchData(num);
}

8๏ธโƒฃ ๐Ÿ’ผ ๋น„๋™๊ธฐ + ์—๋Ÿฌ ํ•ธ๋“ค๋ง ์‹ฌํ™”

โœ… try-catch-finally ํŒจํ„ด

async function robustFetch() {
  try {
    const res = await fetch('url');
    if(!res.ok) throw new Error('Server error!');
    const data = await res.json();
    return data;
  } catch (err) {
    console.error('Handled:', err);
  } finally {
    console.log('Cleanup');
  }
}

9๏ธโƒฃ ๐Ÿง  ๊ธฐ์ˆ  ๋ฉด์ ‘ ๋Œ€๋น„ ํ•ต์‹ฌ ์š”์•ฝ

์งˆ๋ฌธ ํ•ต์‹ฌ ๋‹ต๋ณ€
JS์—์„œ ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•? Callback, Promise, async/await
Callback Hell ๋ฌธ์ œ? ์ค‘์ฒฉ โ†’ ๊ฐ€๋…์„ฑโ†“, ์—๋Ÿฌ ์ฒ˜๋ฆฌ ์–ด๋ ค์›€
Promise ์ƒํƒœ? Pending โ†’ Fulfilled/Rejected
Promise.all, race ์ฐจ์ด? all: ๋ชจ๋‘ ์„ฑ๊ณต ์‹œ ์ง„ํ–‰, race: ๊ฐ€์žฅ ๋น ๋ฅธ ๊ฒƒ
allSettled์™€ any๋Š” ์–ธ์ œ? ์‹คํŒจ ํฌํ•จ ๋ชจ๋“  ๊ฒฐ๊ณผ ํ™•์ธ, ๊ฐ€์žฅ ๋จผ์ € ์„ฑ๊ณต ๋ฐ˜ํ™˜
async/await ๋‚ด๋ถ€ ์›๋ฆฌ? Promise ๊ธฐ๋ฐ˜, ์‹คํ–‰ ์ปจํ…์ŠคํŠธ์— Promise ๋“ฑ๋ก
forEach + await ์‚ฌ์šฉํ•ด๋„ ๋˜๋‚˜? ๋น„์ถ”์ฒœ (ํ๋ฆ„ ์ œ์–ด ๋ถˆ๊ฐ€), forโ€ฆof ์‚ฌ์šฉ
์—๋Ÿฌ ํ•ธ๋“ค๋ง ํŒจํ„ด? try-catch-finally, HTTP ์—๋Ÿฌ๋„ ๋”ฐ๋กœ ํ™•์ธ ํ•„์š”

๐Ÿš€ ์ข…ํ•ฉ ์ •๋ฆฌ ์ฝ”๋“œ ์˜ˆ

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JavaScript ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ฌํ™” ์‹ค์Šต</title>
    <style>
        .area {
            background: lightgray;
            border: 1px solid black;
            width: 600px;
            margin-bottom: 10px;
            padding: 10px;
            white-space: pre-wrap;
            font-family: monospace;
        }
        .big { height: 600px; overflow-y: scroll; }
    </style>
</head>
<body>
    <h2>๐ŸŸข JavaScript ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์‹ฌํ™” ์‹ค์Šต</h2>
    <div class="area big" id="outputArea"></div>
    
    <script>
        function runExamples() {
            const output = document.getElementById("outputArea");
            function log(text) { output.innerHTML += text + "\n"; }
            
            log("โœ… ๋™๊ธฐ vs ๋น„๋™๊ธฐ ์˜ˆ์ œ");
            log("๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰:");
            log("A");
            log("B");
            
            log("\n๋น„๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰:");
            log("A");
            setTimeout(() => log("B (1์ดˆ ํ›„ ์‹คํ–‰)"), 1000); // 1์ดˆ ํ›„ ์‹คํ–‰๋˜๋Š” ๋น„๋™๊ธฐ ์ฝ”๋“œ
            log("C");
            
            log("\nโœ… Event Loop ์ดํ•ด");
            setTimeout(() => log("๐ŸŒŸ ์ด๋ฒคํŠธ ๋ฃจํ”„ ์‹คํ–‰ ์™„๋ฃŒ!"), 0); // ์ด๋ฒคํŠธ ๋ฃจํ”„์˜ ๋™์ž‘ ๋ฐฉ์‹ ํ™•์ธ
            log("๐Ÿ“Œ ๋™๊ธฐ ์ฝ”๋“œ ๋จผ์ € ์‹คํ–‰๋จ");
            
            log("\nโœ… Promise ๊ธฐ๋ณธ ์‚ฌ์šฉ");
            const myPromise = new Promise((resolve) => {
                setTimeout(() => resolve("๐ŸŽ‰ Promise ์„ฑ๊ณต!"), 1500);
            });
            myPromise.then(result => log(result)); // Promise๊ฐ€ ์„ฑ๊ณตํ•˜๋ฉด ์‹คํ–‰
            
            log("\nโœ… async/await ์‚ฌ์šฉ");
            async function fetchData() {
                log("โณ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๋Š” ์ค‘...");
                await new Promise(resolve => setTimeout(resolve, 2000)); // 2์ดˆ ๋Œ€๊ธฐ
                log("โœ… ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์™„๋ฃŒ!");
            }
            fetchData();
            
            log("\nโœ… Promise.all ์‚ฌ์šฉ");
            async function parallelTasks() {
                const [res1, res2] = await Promise.all([
                    new Promise(resolve => setTimeout(() => resolve("๐Ÿ“ฆ ์ž‘์—… 1 ์™„๋ฃŒ"), 1000)),
                    new Promise(resolve => setTimeout(() => resolve("๐Ÿ“ฆ ์ž‘์—… 2 ์™„๋ฃŒ"), 1200))
                ]);
                log(res1);
                log(res2);
            }
            parallelTasks();
            
            log("\nโœ… ์—๋Ÿฌ ํ•ธ๋“ค๋ง");
            async function errorHandlingExample() {
                try {
                    throw new Error("๐Ÿ”ฅ ์˜ค๋ฅ˜ ๋ฐœ์ƒ!");
                } catch (err) {
                    log("โŒ " + err.message); // ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€ ์ถœ๋ ฅ
                } finally {
                    log("๐Ÿ› ๏ธ ์ •๋ฆฌ ์™„๋ฃŒ"); // finally ๋ธ”๋ก ์‹คํ–‰
                }
            }
            errorHandlingExample();

            log("\nโœ… ๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ vs ๋งคํฌ๋กœํƒœ์Šคํฌ");
            setTimeout(() => log("๐Ÿ•’ setTimeout (๋งคํฌ๋กœํƒœ์Šคํฌ)"), 0);
            Promise.resolve().then(() => log("โšก Promise (๋งˆ์ดํฌ๋กœํƒœ์Šคํฌ)"));
            log("๐Ÿ”„ ๋™๊ธฐ ์ฝ”๋“œ ์‹คํ–‰ ์ค‘");
        }
        
        runExamples();
    </script>
</body>
</html>