Modern Asynchronous JavaScript with Async and Await - Lee-hyuna/33-js-concepts-kr GitHub Wiki

์ตœ๊ทผ์— ์“ฐ์ด๊ณ ์žˆ๋Š” ๋น„๋™๊ธฐ ๋ฐฉ์‹์ธ Async, Await

์›๋ฌธ: https://flaviocopes.com/javascript-async-await/

JavaScript์—์„œ ๋น„๋™๊ธฐ์— ๋Œ€ํ•œ ์ ‘๊ทผ ๋ฐฉ์‹์„์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค.
JavaScript๋Š” ์ฝœ๋ฐฑ์— ๋งค์šฐ ์งง์€ ์‹œ๊ฐ„ ๋‚ด์— ์„ฑ์žฅํ–ˆ์œผ๋ฉฐ, Async, Await ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•˜๋ฉด ES2017 ๋น„๋™๊ฐ€ ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.

Introduction

๋น„๋™๊ธฐ ๊ธฐ๋Šฅ์€ Promise๊ณผ Generators์˜ ์กฐํ•ฉ์ด๋ฉฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ Promise๋ณด๋‹ค ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™”์ž…๋‹ˆ๋‹ค.
๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ง์”€๋“œ๋ฆฌ์ง€๋งŒ, Async/Await๋Š” Promise์— ๋”ฐ๋ผ ๋งŒ๋“ค์–ด์ง‘๋‹ˆ๋‹ค.

Why were async/await introduced?

ES2015 Promise๊ฐ€ ๋„์ž…๋˜์—ˆ์„ ๋•Œ, ๋น„๋™๊ธฐ ์ฝ”๋“œ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ES2015์™€ ES2017์„ ๋ถ„๋ฆฌํ•œ 2๋…„ ๋™์•ˆ Promise๋Š” ์ตœ์ข… ํ•ด๊ฒฐ์ฑ…์ด ๋  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ด ๋ช…๋ฐฑํ–ˆ์Šต๋‹ˆ๋‹ค.

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

์ฝ”๋“œ๋ฅผ ๋™๊ธฐ์‹์œผ๋กœ ๋งŒ๋“ค์ง€๋งŒ, ๋’ค์—์„œ ๋น„๋™๊ธฐ์‹์œผ๋กœ ๋ง‰๊ณ  ์ฐจ๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

How it works

๋น„๋™๊ธฐ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ Promise๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

์ด ๊ธฐ๋Šฅ์„ ํ˜ธ์ถœํ•˜๋ ค๋ฉด ๋ฏธ๋ฆฌ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค.
๊ทธ๋Ÿฌ๋ฉด Promise๊ฐ€ ํ•ด๊ฒฐ๋˜๊ฑฐ๋‚˜ ๊ฑฐ๋ถ€๋  ๋•Œ๊นŒ์ง€ call์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค.

ํ•œ ๊ฐ€์ง€ ์ฃผ์˜ ์‚ฌํ•ญ: ํด๋ผ์ด์–ธํŠธ ๊ธฐ๋Šฅ์€ ๋น„๋™๊ธฐ์‹์œผ๋กœ ์ •์˜๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์˜ˆ์ž…๋‹ˆ๋‹ค.

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

A quick example

๋‹ค์Œ์€ ๋น„๋™๊ธฐ์‹์œผ๋กœ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” Async/await์˜ ๊ฐ„๋‹จํ•œ ์˜ˆ์ž…๋‹ˆ๋‹ค.

const doSomethingAsync = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 3000)
  })
}

const doSomething = async () => {
  console.log(await doSomethingAsync())
}

console.log('Before')
doSomething()
console.log('After')

์œ„์˜ ์ฝ”๋“œ๋Š” ๋ธŒ๋ผ์šฐ์ € ์ฝ˜์†”์— ๋‹ค์Œ์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

Before
After
I did something //after 3s

Promise all the things

๋ชจ๋“  ๊ธฐ๋Šฅ์— ๋น„๋™๊ธฐ ํ‚ค์›Œ๋“œ๋ฅผ ์ค€๋น„ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๊ธฐ๋Šฅ์ด Promise๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

๋ช…์‹œ์ ์œผ๋กœ ์•ˆ ํ•˜๊ณ  ์žˆ๋‹ค ํ•˜๋”๋ผ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ Promise๋ฅผ return ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๊ฐ€ ์œ ํšจํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const aFunction = async () => {
  return 'test'
}

aFunction().then(alert) // This will alert 'test'

์•„๋ž˜์˜ ์ฝ”๋“œ์™€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.

const aFunction = async () => {
  return Promise.resolve('test')
}

aFunction().then(alert) // This will alert 'test'

The code is much simpler to read

์œ„์˜ ์˜ˆ์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ๋น„๋™๊ธฐ ์ฝ”๋“œ๋Š” ๋งค์šฐ ๋‹จ์ˆœํ•ด ๋ณด์ž…๋‹ˆ๋‹ค.
Promise, chaining ๋ฐ callback์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์™€ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ๊ฐ€ ํ›จ์”ฌ ๋” ๋ณต์žกํ•  ๋•Œ ์ฃผ์š” ์ด์ ์ด ๋ฐœ์ƒํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, promise๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JSON ๋ฆฌ์†Œ์Šค๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

const getFirstUserData = () => {
  return fetch('/users.json') // get users list
    .then(response => response.json()) // parse JSON
    .then(users => users[0]) // pick first user
    .then(user => fetch(`/users/${user.name}`)) // get user data
    .then(userResponse => userResponse.json()) // parse JSON
}

getFirstUserData()

๋‹ค์Œ์€ Async/Await๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ œ๊ณต๋˜๋Š” ๊ธฐ๋Šฅ๊ณผ ๋™์ผํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

const getFirstUserData = async () => {
  const response = await fetch('/users.json') // get users list
  const users = await response.json() // parse JSON
  const user = users[0] // pick first user
  const userResponse = await fetch(`/users/${user.name}`) // get user data
  const userData = await userResponse.json() // parse JSON
  return userData
}

getFirstUserData()

Multiple async functions in series

๋น„๋™๊ธฐํ•จ์ˆ˜๋Š” ์ฒด์ด๋‹์„ ์ด์šฉํ•ด ์‰ฝ๊ฒŒ ์—ฐ๊ฒฐํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ€๋…์„ฑ๋„ ์ข‹์Šต๋‹ˆ๋‹ค.

const promiseToDoSomething = () => {
  return new Promise(resolve => {
    setTimeout(() => resolve('I did something'), 10000)
  })
}

const watchOverSomeoneDoingSomething = async () => {
  const something = await promiseToDoSomething()
  return something + ' and I watched'
}

const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
  const something = await watchOverSomeoneDoingSomething()
  return something + ' and I watched as well'
}

watchOverSomeoneWatchingSomeoneDoingSomething().then(res => {
  console.log(res)
})

์ถœ๋ ฅ

I did something and I watched and I watched as well