Async/Await ๋ถ„ํ•ด ๐Ÿ”ฅ

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

๊ตฌ๋ฌธ ์„คํƒ•์„ ํŒŒํ—ค์น˜๊ธฐ ์ „์— ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ผ๋ถ€ ์ „์ž„์ž๋ฅผ ์‚ดํŽด๋ณด๊ณ  ์ด ํŒจํ„ด์ด ๋น„๋™๊ธฐ ์„ธ๊ณ„์—์„œ ์ง„์ •์œผ๋กœ ๋ฌ˜์ฑ…์ด ๋  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋ฅผ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ฝœ๋ฐฑ

์ฝœ๋ฐฑ์€ ์•ฝ์†์ด ๋„์ฐฉํ•˜๊ธฐ ์ „์— ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ ์†”๋ฃจ์…˜์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ ํ๋ฆ„๊ณผ ๋ณต์žก์„ฑ์„ ๊ณ ๋ คํ•  ๋•Œ ๋‹น์‹œ javascript์˜ ๊ณ ํ†ต์Šค๋Ÿฌ์šด ๋ถ€๋ถ„ ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค. ์˜ˆ, ๊ฐœ๋ฐœ์ž๋ฅผ ๋งŽ์ด ๊ดด๋กญํ˜”์Šต๋‹ˆ๋‹ค. Inversion of control๋Š” ์ด๋Ÿฌํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํŒจํ„ด์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ ์ฃผ์š” ๊ด€์‹ฌ์‚ฌ ์ค‘ ํ•˜๋‚˜์˜€์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ ์ฝ”๋“œchunk๋ฅผ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

somethirdPartyLibrary.checkout(function doPayment() {
 initiatePayment();
})

ํƒ€์‚ฌ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒดํฌ์•„์›ƒ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜จ๋ผ์ธ ๋ถ€ํŠธ ์บ ํ”„๋ฅผ ์šด์˜ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด ๋ณด์‹ญ์‹œ์˜ค. ๋„์„œ๊ด€์ด ๊ณ ๊ฐ์—๊ฒŒ ์ฒญ๊ตฌํ•  ์‹œ๊ฐ„์„ ๊ฒฐ์ •ํ•˜๋ฉด ์ฝœ๋ฐฑ(doPayment)์„ ํ˜ธ์ถœํ•˜์—ฌ ์ง€๋ถˆ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฝœ๋ฐฑ์„ ํ•œ ๋ฒˆ ํ˜ธ์ถœํ•˜๋ฉด ๋ชจ๋“  ๊ฒƒ์ด ์ •์ƒ์ž…๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋ฌธ์ œ๋กœ ์ธํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ฝœ๋ฐฑ์„ ์—ฌ๋Ÿฌ ๋ฒˆ ํ˜ธ์ถœํ•˜๊ฑฐ๋‚˜ ์ „ํ˜€ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์–ด๋–ป๊ฒŒ ๋ฉ๋‹ˆ๊นŒ? ์ด๋กœ ์ธํ•ด ์‹ฌ๊ฐํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๊ณ ๊ฐ์˜ ์‹ ๋ขฐ๊ฐ€ ๊นจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



์ด๊ฒƒ์ด ์œ„์—์„œ ๋…ผ์˜ํ•œ ์ œ์–ด ์—ญ์ „์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๊ณ ๊ฐ์—๊ฒŒ ์ฒญ๊ตฌํ•˜๋Š” ๊ถŒํ•œ์„ ๋„์„œ๊ด€์— ๋„˜๊ธฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ํ”ผํ•ด์•ผ ํ•  ์ด์ƒํ•œ ํŒจํ„ด ์ค‘ ํ•˜๋‚˜์ด๋ฉฐ ์—ฌ์ „ํžˆ ์‚ฌ์šฉ ์ค‘์ž…๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ตฌ๋… ์ƒํƒœ์— ๋Œ€ํ•ด ๊ณ ๊ฐ์—๊ฒŒ ์•Œ๋ ค์•ผ ํ•œ๋‹ค๋Š” ๊ธฐ๋Šฅ ์š”์ฒญ์ด ์•„๋ฌด๋ฐ๋„ ์˜ค์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ฝœ๋ฐฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

somethirdPartyLibrary.checkout(function doPayment() {
 initiatePayment(function notifyAboutSuccess() {
     showSuccess();
   }, function notifyAboutFailure() {
     showFailure();
   }
 );
})

์ด๋กœ ์ธํ•ด ์ฝœ๋ฐฑ์ด ์—ฌ๋Ÿฌ ๊ฐœ ์ค‘์ฒฉ๋˜๊ณ  ๋‹ค์†Œ ํ˜ผ๋ž€์Šค๋Ÿฝ์Šต๋‹ˆ๋‹ค ๐Ÿ˜“ ๊ทธ๋ ‡์ฃ ? ์ด์ œ ์„ฑ๊ณต ์•Œ๋ฆผ์— ์„ฑ๊ณตํ•ด์•ผ ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ notifyAboutFailure()์— ๋Œ€ํ•œ ์ฝœ๋ฐฑ์œผ๋กœ ์ค‘์ฒฉํ•˜๊ณ  ๊ณง callback hell ์ƒํƒœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ ํ๋ฆ„์€ ์ด์™€ ๊ฐ™์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.



๊ตฌ์ฃผ๊ป˜์„œ ์•ฝ์†ํ•˜์‹œ๋‹ค

๋” ๋งŽ์€ ๊ฒƒ์„ ์œ„ํ•œ ๊ธธ์„ ๋‹ฆ์€ ์•ฝ์†human-readable code . ์•ฝ์†์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

somethirdPartyLibrary.checkout()
.then(initiatePayment)
.then(showSuccess)
.catch(showFailure)


์—ฌ๊ธฐ์—์„œ๋Š” ํ๋ฆ„์ด ๊น”๋”ํ•˜๋ฉฐ ๊ณ ๊ฐ์—๊ฒŒ ์š”๊ธˆ์„ ์ฒญ๊ตฌํ•˜๋Š” ์ œ์–ด๋„ ์šฐ๋ฆฌ์™€ ํ•จ๊ป˜ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ ์‚ฌ์šฉ์ž๋Š” somethirdPartyLibrary.checkout์ด ์—ฌ๋Ÿฌ ๋ฒˆ ํ™•์ธ๋˜๋ฉดthen ์—ฌ๋Ÿฌ ๋ฒˆ ์‹คํ–‰๋ ์ง€ ์˜์‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ์š”, ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Promise๋Š” ํ•œ ๋ฒˆ๋งŒ ํ•ด๊ฒฐ๋˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Promise๋Š” ์ง€๊ธˆ๊นŒ์ง€ ๋งค์šฐ ํ›Œ๋ฅญํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์œ ์ผํ•œ ๊ด€์‹ฌ์‚ฌ๋Š” ์ผ๋ถ€ ์ž‘์—…์ด ํ•ด๊ฒฐํ•  Promise์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ์ž‘์—…์„ then ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์— ๋ž˜ํ•‘ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. asynchronous code ๋ฐฉ์‹์œผ๋กœ synchronous๋ฅผ ์“ธ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๋งˆ๋ฒ• ๊ฐ™์€ ํ•ด๊ฒฐ์ฑ…์€ ๋ฌด์—‡์ผ๊นŒ์š”?

์€์ด์•Œ์ด ์˜จ๋‹ค ๐ŸŽฏ

Async/Await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„์„ ๋‹ค์‹œ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

(async function() {
  try {
    await somethirdPartyLibrary.checkout()
    await initiatePayment();
    showSuccess();
  } catch(err) {
    showFailure(err);
  }
})();


์ด๊ฑด ์ •๋ง ๋งˆ๋ฒ•์ด ๋งž์ฃ ?

๋ฌด๋„ˆ๋œจ๋ฆฌ๋‹ค

์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ํ๋ฆ„์€ javascript์—์„œ Generators๋กœ ๋‹ฌ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ, Async/Await๋Š” ์ƒ์„ฑ๊ธฐ ๋ฐ Promise Underhood์˜ ๋„์›€์œผ๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.

function resumeHandleCheckout() {
    iterator.next();
}

function* handleCheckout() {
    yield someThirdPartyLibrary.checkout();
    yield initiatePayment();
    showSuccess();
}

let iterator = handleCheckout();

let promiseFromLibrary = iterator.next();


promiseFromLibrary
.then(resumeHandleCheckout)
.then(resumeHandleCheckout)
.catch(showFailure);

Async/Await์˜ ์–ธ๋”ํ›„๋“œ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ชจ๋“  ๋ณต์žก์„ฑ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ๊ตฌ๋ฌธ ์„คํƒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

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

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ