๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
JavaScript

[JavaScript] async & await

by curious week 2024. 12. 20.

๐Ÿš€ async / await ์ •๋ฆฌ

async / await๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์„ ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ฃผ๋Š” ์ตœ์‹  JavaScript ๋ฌธ๋ฒ•์ž…๋‹ˆ๋‹ค.
์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ ๋ฐฉ์‹์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ์ฝœ๋ฐฑ ์ง€์˜ฅ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Š


๐Ÿ“Œ async ํ‚ค์›Œ๋“œ

  • async ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ˜ํ™˜๊ฐ’์ด Promise๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ, ์ž๋™์œผ๋กœ Promise.resolve(๋ฐ˜ํ™˜๊ฐ’)์œผ๋กœ ๊ฐ์‹ธ์„œ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

โœ… ์˜ˆ์ œ: async ํ•จ์ˆ˜๋Š” Promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค

async function get1() {
  return '1'; // ์ž๋™์œผ๋กœ Promise.resolve('1')๋กœ ๋ณ€ํ™˜๋จ
}

// ์‹คํ–‰
const one = get1();
one.then((num) => console.log(num)); // ์ถœ๋ ฅ: 1

โœ” get1()์€ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
โœ” .then()์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋ฐ›์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ await ํ‚ค์›Œ๋“œ

  • await ํ‚ค์›Œ๋“œ๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜(async ํ•จ์ˆ˜) ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • await์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•ด๋‹น Promise๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.

โœ… ์˜ˆ์ œ: await์œผ๋กœ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ˆœ์ฐจ ์‹คํ–‰

function network() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('๐Ÿ“ก ๋ฐ์ดํ„ฐ ์š”์ฒญ ์ค‘...');
      resolve('โœ… ๋ฐ์ดํ„ฐ ๋ฐ›์•„์˜ด');
    }, 2000);
  });
}

async function getData() {
  console.log('๐ŸŒ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ์ž‘');
  
  // network() ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋‹ค๋ฆผ
  const result1 = await network();
  console.log(result1); // โœ… ๋ฐ์ดํ„ฐ ๋ฐ›์•„์˜ด

  const result2 = await network();
  console.log(result2); // โœ… ๋ฐ์ดํ„ฐ ๋ฐ›์•„์˜ด

  console.log('๐Ÿš€ ๋ชจ๋“  ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์™„๋ฃŒ!');
}

getData();

โœ” await network();๊ฐ€ ์‹คํ–‰๋  ๋•Œ 2์ดˆ ๋™์•ˆ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๋‹ค์Œ ์ฝ”๋“œ ์‹คํ–‰
โœ” await์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝœ๋ฐฑ ์—†์ด๋„ ๋น„๋™๊ธฐ ์ฝ”๋“œ์˜ ํ๋ฆ„์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํ‘œํ˜„ ๊ฐ€๋Šฅ


๐Ÿ“Œ async / await ์—๋Ÿฌ ์ฒ˜๋ฆฌ

๋น„๋™๊ธฐ ์ž‘์—…์—์„œ ์˜ˆ์™ธ(error)๊ฐ€ ๋ฐœ์ƒํ•  ๊ฒฝ์šฐ, try/catch ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… ์˜ˆ์ œ: try / catch๋กœ ์—๋Ÿฌ ์ฒ˜๋ฆฌ

function networkWithError() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject(new Error('โŒ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ ๋ฐœ์ƒ'));
    }, 2000);
  });
}

async function fetchData() {
  try {
    console.log('๐ŸŒ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ์ž‘');
    const data = await networkWithError(); // ์‹คํŒจ ์‹œ catch ๋ธ”๋ก์œผ๋กœ ์ด๋™
    console.log(`โœ… ๋ฐ์ดํ„ฐ: ${data}`);
  } catch (err) {
    console.error(err.message); // โŒ ๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜ ๋ฐœ์ƒ
  } finally {
    console.log('๐ŸŽฏ ์ž‘์—… ์™„๋ฃŒ (์„ฑ๊ณต/์‹คํŒจ ๊ด€๊ณ„์—†์ด ์‹คํ–‰)');
  }
}

fetchData();

โœ” try ๋ธ”๋ก์—์„œ await์„ ์‚ฌ์šฉํ•˜์—ฌ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹คํ–‰
โœ” reject๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์ฆ‰์‹œ catch ๋ธ”๋ก์œผ๋กœ ์ด๋™ํ•˜์—ฌ ์—๋Ÿฌ ์ฒ˜๋ฆฌ
โœ” **finally**๋Š” ์„ฑ๊ณต/์‹คํŒจ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๋งˆ์ง€๋ง‰์— ํ•ญ์ƒ ์‹คํ–‰๋จ


๐Ÿ“Œ await์˜ ์ค‘์š”์„ฑ

  • await์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๋น„๋™๊ธฐ ์ฝ”๋“œ๊ฐ€ ์ˆœ์„œ๋Œ€๋กœ ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ๋จผ์ € ์‹คํ–‰๋  ์ˆ˜๋„ ์žˆ์Œ
  • await์„ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋จ

โŒ await ์—†์ด ์‹คํ–‰ํ•  ๊ฒฝ์šฐ

async function getDataWithoutAwait() {
  console.log('๐ŸŒ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ์ž‘');

  const result = network(); // `await` ์—†์Œ (๋น„๋™๊ธฐ ์‹คํ–‰)
  console.log(result); // Promise ๊ฐ์ฒด๊ฐ€ ์ถœ๋ ฅ๋จ

  console.log('๐Ÿš€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์™„๋ฃŒ! (๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๊ธฐ ์ „์— ์‹คํ–‰)');
}

getDataWithoutAwait();

๐Ÿ”น ์ถœ๋ ฅ ๊ฒฐ๊ณผ:

plaintext
๋ณต์‚ฌ
๐ŸŒ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์‹œ์ž‘ ๐Ÿš€ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์™„๋ฃŒ! (๋ฐ์ดํ„ฐ๊ฐ€ ์˜ค๊ธฐ ์ „์— ์‹คํ–‰) Promise { <pending> }

โœ” await์ด ์—†์–ด์„œ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „์— ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋จ


๐Ÿ“Œ async / await vs Promise.then()

๋น„๊ตํ•ญ๋ชฉ async / await Promise.then()
๊ฐ€๋…์„ฑ ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์ฝ๊ธฐ ์‰ฌ์›€ โœ… ์ฝœ๋ฐฑ์ด ๋งŽ์•„์ง€๋ฉด ๋ณต์žกํ•ด์ง โŒ
์—๋Ÿฌ ์ฒ˜๋ฆฌ try / catch๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌ โœ… .catch()๋ฅผ ๋”ฐ๋กœ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ โŒ
์ฒด์ด๋‹ ์ง๊ด€์  โœ… .then().then() ๋ฐฉ์‹์œผ๋กœ ์ด์–ด์ง โŒ
๋ณ‘๋ ฌ ์‹คํ–‰ Promise.all() ํ•„์š” โŒ ์›๋ž˜ ๋ณ‘๋ ฌ ์‹คํ–‰ ๊ฐ€๋Šฅ โœ…

โœ… Promise.then() ๋ฐฉ์‹

network()
  .then((data) => {
    console.log(data);
    return network();
  })
  .then((data) => {
    console.log(data);
  })
  .catch((err) => console.error(err));

โœ… async / await ๋ฐฉ์‹

async function fetchData() {
  try {
    const data1 = await network();
    console.log(data1);

    const data2 = await network();
    console.log(data2);
  } catch (err) {
    console.error(err);
  }
}

fetchData();

โœ” async / await์„ ์‚ฌ์šฉํ•˜๋ฉด ์ฝ”๋“œ๊ฐ€ ๋™๊ธฐ ๋ฐฉ์‹์ฒ˜๋Ÿผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฝํž˜
โœ” Promise.then()๋ณด๋‹ค ์—๋Ÿฌ ์ฒ˜๋ฆฌ๊ฐ€ ์ง๊ด€์ 


๐Ÿ“Œ Promise.all()์„ ํ™œ์šฉํ•œ ๋ณ‘๋ ฌ ์‹คํ–‰

๐Ÿ‘‰ await์„ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•˜๋ฉด ์ž‘์—…์ด ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฏ€๋กœ ์†๋„๊ฐ€ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ์Œ
๐Ÿ‘‰ ์—ฌ๋Ÿฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋ ค๋ฉด Promise.all()์„ ์‚ฌ์šฉํ•ด์•ผ ํ•จ

โœ… ์ˆœ์ฐจ ์‹คํ–‰ (๋น„ํšจ์œจ์ )

async function fetchSequential() {
  const data1 = await network();
  console.log(data1);

  const data2 = await network();
  console.log(data2);
}

fetchSequential();
 

โœ” network()๊ฐ€ ๋๋‚œ ํ›„ ๋‹ค์Œ ์ž‘์—…์ด ์‹œ์ž‘๋จ (์ด 4์ดˆ ์†Œ์š”)

โœ… ๋ณ‘๋ ฌ ์‹คํ–‰ (ํšจ์œจ์ )

async function fetchParallel() {
  const [data1, data2] = await Promise.all([network(), network()]);
  console.log(data1, data2);
}

fetchParallel();

โœ” Promise.all()์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ชจ๋“  ์ž‘์—…์ด ๋™์‹œ์— ์‹คํ–‰๋˜์–ด ๋” ๋น ๋ฅด๊ฒŒ ์™„๋ฃŒ๋จ ๐Ÿš€


๐Ÿ“Œ ์ •๋ฆฌ

  • async → ํ•จ์ˆ˜๊ฐ€ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ๋ณ€ํ™˜
  • await → Promise๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๋‹ค์Œ ์ฝ”๋“œ ์‹คํ–‰
  • try / catch → async / await์—์„œ ์—๋Ÿฌ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•
  • finally → ์„ฑ๊ณต/์‹คํŒจ์™€ ๊ด€๊ณ„์—†์ด ๋งˆ์ง€๋ง‰์— ์‹คํ–‰
  • Promise.all() → ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋น„๋™๊ธฐ ์ž‘์—…์„ ๋ณ‘๋ ฌ ์‹คํ–‰ํ•˜์—ฌ ์†๋„ ํ–ฅ์ƒ

๐Ÿ“ข async / await์„ ์‚ฌ์šฉํ•˜๋ฉด ๋น„๋™๊ธฐ ์ฝ”๋“œ๋ฅผ ๋™๊ธฐ ์ฝ”๋“œ์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿš€


// promise๋ฅผ ๊ฐ์‹ธ์„œ ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“ค์–ด์ค€๋‹ค.

// Async: ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๋Š” ํ‚ค์›Œ๋“œ
// async -> promise๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ๋ณ€ํ™˜
async function get1() {
  return '1';
}
// async ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์œผ๋ฉด ํ•ญ์ƒ promise๋กœ ๋ฆฌํ„ด
const one = get1();
one.then((num) => console.log(num));
// async ํ•จ์ˆ˜ ์•ˆ์—์„œ promise๋ฅผ ๋ฆฌํ„ดํ•˜๋ฉด promise๋กœ ๊ฐ์‹ธ์ง€ ์•Š๋Š”๋‹ค.

function network() {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('data');
      resolve('data resolve');
    }, 2000);
  });
}
async function getData() {
  // await์€ async ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ๋งŒ ์‹คํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.
  // await์ด ์—†๋‹ค๋ฉด ๋น„๋™๊ธฐ์ ์œผ๋กœ console.log('dataReturn') ๊ฐ’์ด ๋จผ์ € ํ‘œ์‹œ๋œ๋‹ค.
  // ์ˆœ์ฐจ์ ์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
  await network();
  await network();
  // async ๋‚ด๋ถ€์—์„œ ์—๋Ÿฌ์ฒ˜๋ฆฌ
  try {
    const net = await network();
  } catch (err) {
    console.log(err);
    // ์—๋Ÿฌ ์‹œ ๋Œ€์‹  ๋„ฃ์„ ๊ฐ’์„ ๋ฆฌํ„ด
    net = 'data reject';
  }
  return console.log(`return ${net}`);
}

 

 

 

'JavaScript' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[JavaScript] ๊ตฌ์กฐ ๋ถ„ํ•ด ํ• ๋‹น  (4) 2024.12.22
[JavaScript] Reduce  (5) 2024.12.22
[JavaScript] ์ฝœ๋ฐฑํ•จ์ˆ˜  (3) 2024.12.20
[JavaScript] Fetch, AJAX, Axios  (2) 2024.12.20
[JavaScript] Promise  (0) 2024.12.20