23. Front-end/23. html css javascript

async ํ•จ์ˆ˜์™€ await

keemzeehae 2024. 8. 19. 16:44

 

์™œ ์‚ฌ์šฉํ•˜์ง€?

 

async ํ•จ์ˆ˜๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, ์–ด๋–ค ์ž‘์—…์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค.

async ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ์ด๋Ÿฌํ•œ ์ž‘์—…์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ์ž‘์—…์„ ๋จผ์ € ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค!

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ”„๋กœ๊ทธ๋žจ์˜ ํšจ์œจ์„ฑ์ด ๋†’์•„์ง€๊ณ , ํŠนํžˆ I/O ์ž‘์—…์ด๋‚˜ ๋„คํŠธ์›Œํฌ ์š”์ฒญ ๊ฐ™์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์—์„œ ์œ ์šฉํ•˜๋‹ค.

 

async (์–ด์‹ฑํฌ)ํ•จ์ˆ˜ ๋ฌธ๋ฒ• 

 

async๋Š” function ์•ž์— ์œ„์น˜ํ•œ๋‹ค.

async function f() {

      return 1;

}

 

function ์•ž์— async๋ฅผ ๋ถ™์ด๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋Š” ํ•ญ์ƒ ํ”„๋ผ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋”๋ผ๋„ ์ดํ–‰ ์ƒํƒœ์˜ ํ”„๋ผ๋ฏธ์Šค(resolved promise)๋กœ ๊ฐ’์„ ๊ฐ์‹ธ ์ดํ–‰๋œ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•œ๋‹ค.

์•„๋ž˜ ์˜ˆ์‹œ์˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด result๊ฐ€ 1์ธ ์ดํ–‰ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ๋ฐ˜ํ™˜๋œ๋‹ค.

async function f() {

    return 1;

}

f().then(alert); // 1

 

 

์•„๋ž˜์ฒ˜๋Ÿผ ๋ช…์‹œ์ ์œผ๋กœ ํ”„๋ผ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•œ๋ฐ, ๊ฒฐ๊ณผ๋Š” ๋™์ผํ•˜๋‹ค.

async function f() {
    return Promise.resolve(1);
}
 
f().then(alert); // 1

 

 

async๊ฐ€ ๋ถ™์€ ํ•จ์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ํ”„๋ผ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์•„๋‹Œ ๊ฒƒ์€ ํ”„๋ผ๋ฏธ์Šค๋กœ ๊ฐ์‹ธ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

โ—๏ธasync๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์ด๋ฟ๋งŒ์ด ์•„๋‹ˆ๋‹ค.

โ—๏ธ๋˜ ๋‹ค๋ฅธ ํ‚ค์›Œ๋“œ await๋Š” async ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ๋™์ž‘ํ•œ๋‹ค.

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” await ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

await๋Š” '๊ธฐ๋‹ค๋ฆฌ๋‹ค’๋ผ๋Š” ๋œป์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ, ์˜์–ด ๋œป๋Œ€๋กœ ๊ฒฐ๊ณผ๋Š” ๊ทธ ์ดํ›„ ๋ฐ˜ํ™˜๋œ๋‹ค.

 

1์ดˆ ํ›„ ์ดํ–‰๋˜๋Š” ํ”„๋ผ๋ฏธ์Šค๋ฅผ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉํ•˜์—ฌ await๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด๋ฉด

async function f() {

    let promise =newPromise((resolve, reject) => {

        setTimeout(() => resolve("์™„๋ฃŒ!"), 1000)

    });

let result = await promise; // ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ดํ–‰๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆผ (*)

alert(result); // "์™„๋ฃŒ!"

}

 

f();

 

ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ํ•จ์ˆ˜ ๋ณธ๋ฌธ์ด ์‹คํ–‰๋˜๋Š” ๋„์ค‘์— (*)๋กœ ํ‘œ์‹œํ•œ ์ค„์—์„œ ์‹คํ–‰์ด ์ž ์‹œ '์ค‘๋‹จ’๋˜์—ˆ๋‹ค๊ฐ€ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋ฉด ์‹คํ–‰์ด ์žฌ๊ฐœ๋œ๋‹ค.

์ด๋•Œ ํ”„๋ผ๋ฏธ์Šค ๊ฐ์ฒด์˜ result ๊ฐ’์ด ๋ณ€์ˆ˜ result์— ํ• ๋‹น๋œ๋‹ค. ๋”ฐ๋ผ์„œ ์œ„ ์˜ˆ์‹œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 1์ดˆ ๋’ค์— '์™„๋ฃŒ!'๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.

 

await๋Š” ๋ง ๊ทธ๋Œ€๋กœ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋  ๋•Œ๊นŒ์ง€ ํ•จ์ˆ˜ ์‹คํ–‰์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ๋งŒ๋“ ๋‹ค. ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋˜๋ฉด ๊ทธ ๊ฒฐ๊ณผ์™€ ํ•จ๊ป˜ ์‹คํ–‰์ด ์žฌ๊ฐœ๋˜์ฃ . ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์ฒ˜๋ฆฌ๋˜๊ธธ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ์—” ์—”์ง„์ด ๋‹ค๋ฅธ ์ผ(๋‹ค๋ฅธ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰, ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ ๋“ฑ)์„ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, CPU ๋ฆฌ์†Œ์Šค๊ฐ€ ๋‚ญ๋น„๋˜์ง€ ์•Š๋Š”๋‹ค.

 

 

โ—๏ธ์ผ๋ฐ˜ ํ•จ์ˆ˜์—” await์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค

async ํ•จ์ˆ˜๊ฐ€ ์•„๋‹Œ๋ฐ await์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ๋ฒ• ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 
function f() {
  let promise = Promise.resolve(1);
  let result = await promise; // Syntax error
}

function ์•ž์— async๋ฅผ ๋ถ™์ด์ง€ ์•Š์œผ๋ฉด ์ด๋Ÿฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์•ž์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ด await๋Š” async ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ๋™์ž‘ํ•œ๋‹ค.

 

โ—๏ธ์ฃผ์˜ํ•ด์•ผ ํ•  ์ 

await๋Š” ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ ์ฝ”๋“œ์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค.
// ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ ์ฝ”๋“œ์—์„  ๋ฌธ๋ฒ• ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();

ํ•˜์ง€๋งŒ ์ต๋ช… async ํ•จ์ˆ˜๋กœ ์ฝ”๋“œ๋ฅผ ๊ฐ์‹ธ๋ฉด ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ ์ฝ”๋“œ์—๋„ await๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(async () => {
  let response = await fetch('/article/promise-chaining/user.json');
  let user = await response.json();
  ...
})();

 

 

 

๐ŸŒ€ ์ถ”๊ฐ€ ์ •๋ณด

1. await๋Š” ‘thenable’ ๊ฐ์ฒด๋ฅผ ๋ฐ›๋Š”๋‹ค.

promise.then์ฒ˜๋Ÿผ await์—๋„ thenable ๊ฐ์ฒด(then ๋ฉ”์„œ๋“œ๊ฐ€ ์žˆ๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

thenable ๊ฐ์ฒด๋Š” ์„œ๋“œํŒŒํ‹ฐ ๊ฐ์ฒด๊ฐ€ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ ํ”„๋ผ๋ฏธ์Šค์™€ ํ˜ธํ™˜ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ์ƒ๊ธด ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ์„œ๋“œํŒŒํ‹ฐ์—์„œ ๋ฐ›์€ ๊ฐ์ฒด๊ฐ€ .then์„ ์ง€์›ํ•˜๋ฉด ์ด ๊ฐ์ฒด๋ฅผ await์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

("์„œ๋“œํŒŒํ‹ฐ์—์„œ ๋ฐ›์€ ๊ฐ์ฒด"๋ผ๋Š” ๊ฒƒ์€ ๋‹น์‹ ์ด ๋งŒ๋“  ์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ์™ธ๋ถ€์—์„œ ์ œ๊ณต๋œ ์ฝ”๋“œ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์ „๋‹ฌ๋œ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๊ฐ€ .then ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์›ํ•œ๋‹ค๋ฉด, ์ด ๊ฐ์ฒด๋ฅผ await์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.)

 

await๋Š” ํด๋ž˜์Šค Thenable์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

 

lass Thenable {
  constructor(num) {
    this.num = num;
  }
  then(resolve, reject) {
    alert(resolve);
    // 1000๋ฐ€๋ฆฌ์ดˆ ํ›„์— ์ดํ–‰๋จ(result๋Š” this.num*2)
    setTimeout(() => resolve(this.num * 2), 1000); // (*)
  }
};

async function f() {
  // 1์ดˆ ํ›„, ๋ณ€์ˆ˜ result๋Š” 2๊ฐ€ ๋จ
  let result = await new Thenable(1);
  alert(result);
}

f();
 
await๋Š” .then์ด ๊ตฌํ˜„๋˜์–ด์žˆ์œผ๋ฉด์„œ ํ”„๋ผ๋ฏธ์Šค๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด๋ฅผ ๋ฐ›์œผ๋ฉด, ๋‚ด์žฅ ํ•จ์ˆ˜ resolve์™€ reject๋ฅผ ์ธ์ˆ˜๋กœ ์ œ๊ณตํ•˜๋Š” ๋ฉ”์„œ๋“œ์ธ .then์„ ํ˜ธ์ถœํ•œ๋‹ค.(์ผ๋ฐ˜ Promise executor๊ฐ€ ํ•˜๋Š” ์ผ๊ณผ ๋™์ผํ•˜๋‹ค).
๊ทธ๋ฆฌ๊ณ  ๋‚˜์„œ await๋Š” resolve์™€ reject ์ค‘ ํ•˜๋‚˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธธ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€((*)๋กœ ํ‘œ์‹œํ•œ ์ค„) ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ง€๊ณ  ๋‹ค์Œ ์ผ์„ ์ง„ํ–‰ํ•œ๋‹ค.
 
 
2. async ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ

: ๋ฉ”์„œ๋“œ ์ด๋ฆ„ ์•ž์— async๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด async ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 
class Waiter {
  async wait() {
    return await Promise.resolve(1);
  }
}

new Waiter()
  .wait()
  .then(alert); // 1

async ๋ฉ”์„œ๋“œ์™€ async ํ•จ์ˆ˜๋Š” ํ”„๋ผ๋ฏธ์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  await๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์—์„œ ๋™์ผํ•˜๋‹ค.

 

 

์ฐธ๊ณ ์ž๋ฃŒ

https://ko.javascript.info/async-await#ref-69

 

async์™€ await

 

ko.javascript.info