async와 await은 promise를 간편하고 동기적으로 실행되는것처럼 보여준다.
async function 함수명() {
await 비동기_처리_메서드_명();
}
function fetchUser() {
// do network 10 sec.....
return 'minbro'
}
const user = fetchUser()
console.log(user)
/* 화면 보이는 코드 */
여기서 async를 하지 않는다면, fetchUser가 끝날때까지 계속 기다렸다가 그 이후에 화면을 출력한다. 유저는 그동안 계속 빈 화면만 보는 상황이 발생한다.
따라서 앞서 배운 Promise를 사용한다면 이와 같다.
function fetchUser() {
return new Promise((resolve, reject) => {
// do network 10 sec.....
resolve('minbro')
})
}
const user = fetchUser()
user.then(console.log)
console.log(user)
// Promise {<fulfilled>: "minbro"}
// minbro
이처럼 번거롭게 resolve, reject, Promise를 사용하지 않고 async를 사용하여 표현할 수도 있다.
async function fetchUser() {
// do network 10 sec.....
return 'minbro'
}
const user = fetchUser()
user.then(console.log)
console.log(user)
// Promise {<fulfilled>: "minbro"}
// minbro
async를 사용하더라도 promise를 바로 사용할 수 있다!
Syntactic Sugar!
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function getApple() {
await delay(3000)
return '🍎'
}
async function getBanana() {
await delay(3000)
return '🍌'
}
async function pickFruits() {
const apple = await getApple()
const banana = await getBanana()
return `${apple} + ${banana}`
}
pickFruits().then(console.log)
// 6초 후
// 🍎 + 🍌
여기서 문제점은, 각각 사과와 바나나를 출력하는데 3초씩, 도합 6초가 걸린다는것이다! 병렬처리가 필요한 시점이다!
function pickAllFruits() {
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join(' + '))
}
pickAllFruits().then(console.log)
Promise의 all이라는 api를 사용하면 된다!
=> Promise 배열을 전달하면, 모든 Promise들이 병렬적으로 작업을 끝낼때까지 모아주는 역할!
여기서는 [getApple(), getBanana()]를 전달했기 때문에, 결과값은 [🍎,🍌] 가 된다. 따라서 이를 join을 사용해서 string으로 만든것!
function pickOnlyOne() {
return Promise.race([getApple(), getBanana()])
}
pickOnlyOne().then(console.log)
race라는 api를 사용하면, 가장 먼저 값을 return하는 Promise만 그 값을 전달한다!