๊ด๋ จ ํค์๋
์ง์ฐ ์์ ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ์๋ต์ฑ ํฅ์์ผ๋ก ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์
์์์ ์ต์ ํ(์ฑ๋ฅ ์ต์ ํ)
์๋ฐ์คํฌ๋ฆฝํธ๋ ๋จ์ผ ์ค๋ ๋(Single-threaded) ์ธ์ด๋ก, ํ ๋ฒ์ ํ๋์ ์์
๋ง ์ฒ๋ฆฌํ ์ ์๋ค. ์ด๋ ์ฝ๋๊ฐ ์์ฐจ์ ์ผ๋ก ์คํ๋๋ค๋ ์๋ฏธ์ธ๋ฐ, ๋ง์ฝ ๋ชจ๋ ์์
์ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ค๋ฉด ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์
(์: ์๋ฒ ์์ฒญ, ํ์ผ ์ฝ๊ธฐ)์ด ๋๋ ๋๊น์ง ํ๋ก๊ทธ๋จ ์ ์ฒด๊ฐ ๋ฉ์ถฐ๋ฒ๋ฆด ์ ์๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ๋น๋๊ธฐ ํจ์๋ฅผ ์ฌ์ฉํ๋๋ฐ ์ด๋ ์๊ฐ ์ง์ฐ ์์
์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ณ , ์ฌ์ฉ์ ๊ฒฝํ์ ๊ฐ์ ํ๋ฉฐ, ์์์ ์ต์ ํ ํ ์ ์๊ฒ ํด์ค๋ค. ์ด๋ฌํ ํน์ฑ ๋๋ถ์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ ์น ๊ฐ๋ฐ์์ ํ์์ ์ธ ์์๋ก ์๋ฆฌ ์ก์์ผ๋ฉฐ, Promise์ async/await๋ฅผ ํ์ฉํ๋ฉด ๋์ฑ ๊ฐ๋ ฅํ๊ณ ๊น๋ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
๐ ์๊ฐ ์ง์ฐ ์์ ์ฒ๋ฆฌ์ ๋ํด ์๋ต์ฑ ํฅ์
๋คํธ์ํฌ ์์ฒญ(์: API ํธ์ถ), ํ์ผ ์
์ถ๋ ฅ, ํ์ด๋จธ(setTimeout) ๋ฑ์ ๊ฒฐ๊ณผ๋ฅผ ์ฆ์ ์ป์ ์ ์๋ ์์
์ด๋ค. ๋๊ธฐ ๋ฐฉ์์ผ๋ก ์ฒ๋ฆฌํ๋ฉด ์๋ต์ด ์ฌ ๋๊น์ง ํ๋ก๊ทธ๋จ์ด ๋๊ธฐ ์ํ์ ๋น ์ง๊ฒ ๋๋ค.
์๋ฅผ๋ค๋ฉด ์ฌ์ฉ์๊ฐ ์น์ฌ์ดํธ์์ ๋ฒํผ์ ๋๋ ์ ๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ 3์ด๊ฐ ๊ฑธ๋ฆฐ๋ค๋ฉด, ๋๊ธฐ ๋ฐฉ์์์๋ 3์ด ๋์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฉ์ถฐ ์ฌ์ฉ์ ๊ฒฝํ์ด ๋๋น ์ง๋ ๊ฒฝํ์ด ์๋ค.
์์ ๊ฐ์ ์ํฉ์์ ๋น๋๊ธฐ ํจ์๋ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์ ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ , ๋ค๋ฅธ ์์ ์ ๋ณ๋ ฌ์ ์ผ๋ก ์ํํ ์ ์์ด ์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ๋ฒํผ์ ๋๋ ์ ๋ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ณ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ "๋ก๋ฉ ์ค" ๋ฉ์์ง๋ฅผ ํ์ํ๋ฉฐ, ์ฌ์ฉ์๊ฐ ํ๋ฉด์ ์คํฌ๋กคํ๊ฑฐ๋ ๋ค๋ฅธ ๋ฒํผ์ ํด๋ฆญํ ์ ์๊ฒ ํด์ค๋ค.
์๋ฅผ๋ค๋ฉด ์ฌ์ฉ์๊ฐ ์น์ฌ์ดํธ์์ ๋ฒํผ์ ๋๋ ์ ๋ ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ 3์ด๊ฐ ๊ฑธ๋ฆฐ๋ค๋ฉด, ๋๊ธฐ ๋ฐฉ์์์๋ 3์ด ๋์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋ฉ์ถฐ ์ฌ์ฉ์ ๊ฒฝํ์ด ๋๋น ์ง๋ ๊ฒฝํ์ด ์๋ค.
์์ ๊ฐ์ ์ํฉ์์ ๋น๋๊ธฐ ํจ์๋ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๋ ์์ ์ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ , ๋ค๋ฅธ ์์ ์ ๋ณ๋ ฌ์ ์ผ๋ก ์ํํ ์ ์์ด ์ฌ์ฉ์๊ฐ ํ์๊ฐ์ ๋ฒํผ์ ๋๋ ์ ๋ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ณ ์๋ต์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ "๋ก๋ฉ ์ค" ๋ฉ์์ง๋ฅผ ํ์ํ๋ฉฐ, ์ฌ์ฉ์๊ฐ ํ๋ฉด์ ์คํฌ๋กคํ๊ฑฐ๋ ๋ค๋ฅธ ๋ฒํผ์ ํด๋ฆญํ ์ ์๊ฒ ํด์ค๋ค.
๐ ์ฌ์ฉ์ ๊ฒฝํ(UX) ๊ฐ์
์์์๋ ์ด์ผ๊ธฐ ํ์ง๋ง ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ํตํด ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ ์์
์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํํ์ฌ, ๊ทธ ๋์ ์ฌ์ฉ์๊ฐ ๋ค๋ฅธ ์ธํฐ๋์
์ ๊ณ์ํ ์ ์๋๋ก ํด์ค๋ค.์๋ฅผ ๋ค๋ฉด ์ ํ๋ธ์์ ๋์์ ๋ก๋ฉ ์ค์๋ ์ฌ์ฉ์๊ฐ ๋๊ธ์ ์ฝ๊ฑฐ๋ ์ข์์๋ฅผ ๋๋ฅผ ์ ์๋ ์ด์ ๊ฐ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๋๋ถ์ด๋ค.
๐ ์์ ํจ์จ์ฑ
์์
์ด ์๋ฃ๋๊ธฐ๋ฅผ ๊ธฐ๋ค๋ฆฌ๋ ๋์ CPU์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ํด ์ํ๋ก ๋์ง ์๊ณ , ๋ค๋ฅธ ์์
์ ์ํํ ์ ์์ด ์์์ ํจ์จ์ ์ผ๋ก ํ์ฉํ ์ ์๋ค.
๐ ํ์ค์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์๊ตฌ์ฌํญ
ํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์
์ ๋ค์ค ์์
, ์ฆ ๋ฐ์ดํฐ ๋ก๋, ์ด๋ฏธ์ง ๋ ๋๋ง, ์ฌ์ฉ์ ์
๋ ฅ ์ฒ๋ฆฌ์ ๋์์ ์ฒ๋ฆฌํด์ผ ํ๋๋ฐ, ์ด๋ฅผ ๋น๋๊ธฐ ๋ฐฉ์์ผ๋ก๋ง ๊ตฌํํ ์ ์๋ค.
๊ฐ๋ ์ฑ๊ณผ ์ ์ง๋ณด์์ฑ ๊ฐ์ aync/await
async/await๋ ES2017(ECMAScript 2017)์์ ๋์
๋ ๋น๋๊ธฐ ์์
์ฒ๋ฆฌ ๋ฌธ๋ฒ์ผ๋ก, ๋น๋๊ธฐ ์ฝ๋๋ฅผ ๋ณด๋ค ๊ฐ๊ฒฐํ๊ณ ์ง๊ด์ ์ผ๋ก ์์ฑํ ์ ์๊ฒ ํด์ค๋ค. ๊ธฐ์กด์ ์ฝ๋ฐฑ ํจ์๋ฅผ ์ฐ์์ ์ผ๋ก ํธ์ถํ๋ ๋ฐฉ์์ ๊ฐ๋
์ฑ์ด ๋จ์ด์ง๊ณ ๋ก์ง ์์ ์ด ์ด๋ ค์ด "์ฝ๋ฐฑ ์ง์ฅ(callback hell)" ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์๋๋ฐ async/await๋ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ฉฐ, ๋น๋๊ธฐ ์์
์ ๋๊ธฐ ์ฝ๋์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ค.
- async ํค์๋๋ก ์ ์๋ ํจ์๋ ํญ์ Promise ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค.
- async ํจ์ ๋ด๋ถ์์ ์ฌ์ฉ๋๋ฉฐ, ๋น๋๊ธฐ ์์ (Promise)์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค.
// ์ฝ๋ฐฑ ๋ฐฉ์ getData(function (data) { processData(data, function (result) { saveData(result, function (response) { console.log(response); }); }); }); // async/await ๋ฐฉ์ async function handleData() { const data = await getData(); const result = await processData(data); const response = await saveData(result); console.log(response); }
- ์๋ฌ ์ฒ๋ฆฌ: try/catch ๋ฌธ์ ์ฌ์ฉํด ๋น๋๊ธฐ ์์ ์ค ๋ฐ์ํ ์ค๋ฅ๋ฅผ ๊น๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
async function fetchUserData() { try { const response = await fetch('https://api.example.com/users'); const data = await response.json(); console.log('์ฌ์ฉ์ ๋ฐ์ดํฐ:', data); } catch (error) { console.error('์๋ฌ ๋ฐ์:', error); } } fetchUserData();
์ ์ฝ๋์์ fetch๋ ๋น๋๊ธฐ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ํจ์์ด๋ค. await๋ฅผ ์ฌ์ฉํด ์๋ต์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฐ ํ, JSON ๋ฐ์ดํฐ๋ฅผ ํ์ฑํ๋ค. ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด catch ๋ธ๋ก์์ ์ฒ๋ฆฌ๋๋ค. async/await ๋ฐฉ์์ด ํจ์ฌ ์ฝ๊ธฐ ์ฝ๊ณ ๋๋ฒ๊น
๋ ๊ฐํธํด์ง๋ค.
Promise๋
Promise๋ ๋น๋๊ธฐ ์์
์ ๋ค๋ฃจ๊ธฐ ์ํ ๊ฐ์ฒด๋ก, ์์
์ ์ฑ๊ณต(resolve) ๋๋ ์คํจ(reject) ์ํ๋ฅผ ๋ช
ํํ ๊ด๋ฆฌํ ์ ์๊ณ ๋น๋๊ธฐ ์์
์ ํ๋ฆ์ ์ฒด๊ณ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
๐ ๊ตฌ์ฑ
new Promise ์์ฑ์๋ฅผ ํตํด ์ ์๋๋ฉฐ, ๋ด๋ถ์์ resolve ๋๋ reject ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
const myPromise = new Promise((resolve, reject) => { // ๋น๋๊ธฐ ์์ ์๋ฎฌ๋ ์ด์ (์: 2์ด ํ ๊ฒฐ๊ณผ ๋ฐํ) setTimeout(() => { const success = true; // ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ์๋ฎฌ๋ ์ด์ if (success) { resolve("์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!"); // ์ฑ๊ณต ์ resolve ํธ์ถ } else { reject("์์ ์ด ์คํจํ์ต๋๋ค."); // ์คํจ ์ reject ํธ์ถ } }, 2000); }); // Promise ์ฌ์ฉ myPromise .then((result) => { console.log(result); // 2์ด ํ: "์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!" }) .catch((error) => { console.error(error); // ์คํจ ์ ์ถ๋ ฅ });
๐ ์ํ
- pending : ๋น๋๊ธฐ ์์ ์ด ์์ง ์๋ฃ๋์ง ์์ ์ํ
- fulfilled : ๋น๋๊ธฐ ์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋ ์ํ
- reject : ๋น๋๊ธฐ ์์ ์ด ์คํจํ ์ํ
function simulateAsyncTask(delay, shouldSucceed) { return new Promise((resolve, reject) => { console.log("์ํ: pending - ์์ ์ด ์์๋์์ผ๋ฉฐ ์์ง ์๋ฃ๋์ง ์์์ต๋๋ค."); setTimeout(() => { if (shouldSucceed) { resolve("์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!"); // ์ํ: fulfilled - ์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ๋๋ ์ํ } else { reject(new Error("์์ ์ด ์คํจํ์ต๋๋ค.")); // ์ํ: rejected - ์์ ์ด ์คํจํ ์ํ } }, delay); }); } // 1. ์ฑ๊ณต ์ผ์ด์ค (fulfilled ์ํ๋ก ์ ํ) const successPromise = simulateAsyncTask(2000, true); console.log("Promise ์์ฑ ์งํ:", successPromise); // Promise { <pending> } successPromise .then((result) => { console.log("์ํ: fulfilled -", result); // 2์ด ํ: "์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!" console.log("Promise ์ํ ํ์ธ:", successPromise); // Promise { "์์ ์ด ์ฑ๊ณต์ ์ผ๋ก ์๋ฃ๋์์ต๋๋ค!" } }) .catch((error) => { console.error("์๋ฌ:", error.message); }); // 2. ์คํจ ์ผ์ด์ค (rejected ์ํ๋ก ์ ํ) const failPromise = simulateAsyncTask(1500, false); console.log("Promise ์์ฑ ์งํ:", failPromise); // Promise { <pending> } failPromise .then((result) => { console.log(result); }) .catch((error) => { console.log("์ํ: rejected -", error.message); // 1.5์ด ํ: "์์ ์ด ์คํจํ์ต๋๋ค." console.log("Promise ์ํ ํ์ธ:", failPromise); // Promise { <rejected> Error: ์์ ์ด ์คํจํ์ต๋๋ค. } });
๐ ๋ฉ์๋
- .then(): ์ฑ๊ณต ์ ํธ์ถ.
- .catch(): ์คํจ ์ ํธ์ถ.
function fetchData() { return new Promise((resolve, reject) => { setTimeout(() => { const success = true; // ์ฑ๊ณต ์ฌ๋ถ ์๋ฎฌ๋ ์ด์ if (success) { resolve('๋ฐ์ดํฐ ๋ก๋ ์ฑ๊ณต'); } else { reject('๋ฐ์ดํฐ ๋ก๋ ์คํจ'); } }, 2000); }); } fetchData() .then((result) => console.log(result)) // 2์ด ํ: "๋ฐ์ดํฐ ๋ก๋ ์ฑ๊ณต" .catch((error) => console.error(error)); // ์คํจ์ ํธ์ถ
Promise ๊ฐ์ฒด๋ ๋น๋๊ธฐ ์์
์ ์ฑ๊ณต/์คํจ๋ฅผ ์ฒ๋ฆฌํ๋ฉฐ .then()๊ณผ .catch()๋ก ๊ฒฐ๊ณผ๋ฅผ ํธ๋ค๋งํฉ๋๋ค.
async/await์ Promise์ ์ฐจ์ด
๐ ์๋ฌ ์ฒ๋ฆฌ
- Promise : .catch()๋ก ์คํจ๋ฅผ ์ฒ๋ฆฌ.
- async/await: try/catch๋ก ์๋ฌ๋ฅผ ํธ๋ค๋ง.
// Promise ๋ฐฉ์ function getData() { fetch('https://api.example.com/data') .then((response) => response.json()) .then((data) => console.log(data)) .catch((error) => console.error(error)); } // async/await ๋ฐฉ์ async function getData() { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } }
ํ์ฅ์ฑ๊ณผ ๋ณ๋ ฌ ์ฒ๋ฆฌ
Promise.all์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๋น๋๊ธฐ ์์
์ ๋ณ๋ ฌ๋ก ์ฒ๋ฆฌํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ ๋ฒ์ ๋ฐ์ ์ ์๋ค. ์ฌ๋ฌ API์์ ๋ฐ์ดํฐ๋ฅผ ๋์์ ๊ฐ์ ธ์์ผ ํ ๋, Promise.all์ ์ฌ์ฉํด ๋ชจ๋ ์์ฒญ์ด ์๋ฃ๋ ํ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํ๋ค.
async function fetchMultipleData() { const [userData, postData] = await Promise.all([ fetch('https://api.example.com/users'), fetch('https://api.example.com/posts'), ]); console.log(await userData.json(), await postData.json()); }