Async 와 Await
체이닝 되는 promise 를 간결하고 간편하게 사용할 수 있고, 비동기 코드를 마치 동기 코드처럼 보이게 작성할 수 있음
Async 사용
async 를 함수 선언 앞에 붙여주게 된다면 함수 내부는 모두 비동기로 바뀌게 된다.
( 함수 내부에 전부 Promise 가 씌워진다고 생각 )
1. promise 를 사용했을 때
const fetchUser = () => {
return new Promise((resolve,reject) => {
resolve('promise')
})
}
const user = fetchUser()
console.log(user)
2. async 를 사용했을 떄
const fetchUser = async () => {
return 'async'
}
const user = fetchUser()
console.log(user)
Await 사용
async 내부에서만 사용 가능.
만약 await가 백엔드를 호출하는 함수 앞에 붙게 된다면 데이터를 가져오는 것이 완료될 때까지 기다려주게 된다.
1. 콜백지옥에 빠지는 경우
const delay = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
const getApple = async () => {
await delay(1000);
return '사과'
}
const getBanana = async () => {
await delay(1000);
return '바나나'
}
const pickFruits = () => {
return getApple().then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`)
})
}
pickFruits().then(console.log)
2. async 와 await 을 사용한 경우
const delay = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
const getApple = async () => {
await delay(1000);
return '사과'
}
const getBanana = async () => {
await delay(1000);
return '바나나'
}
const pickFruits = async () => {
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`
}
pickFruits().then(console.log)
에러 핸들링 (try ... catch)
예외를 처리하기 위한 구문
try {
//예외발생할 가능성이 있는 문장
}catch(Exception1 e1) {
//Exception1이 발생했을 경우, 이를 처리하지 위한 문장적는다.
//보통 이곳에 예외메세지를 출력하고 로그로 남김.
}catch(Exception2 e2) {
//Exception2이 발생했을 경우, 이를 처리하지 위한 문장적는다.
}catch(ExceptionN eN) {
//ExceptionN이 발생했을 경우, 이를 처리하지 위한 문장적는다.
}finally{
//예외발생여부에 관계없이 상항 수행되어야 하는 문장적는다.
}
사용하기
const delay = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
const getApple = async () => {
await delay(1000);
return '사과'
}
const getBanana = async () => {
await delay(1000);
return '바나나'
}
const pickFruits = async () => {
try{
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`
}catch(error){
return error
}
}
pickFruits().then(console.log)
await 병렬 처리
async / await을 사용하여 비동기 작업을 배열로 처리하는 경우 순서가 보장되어야 하는 상황이 아니라면 병렬로 처리해 최적화를 함
Promise.all()
- promise 클래스에 있는 정적 메소드
- 모든 promise 가 이행한 후, 혹은 promise 가 주어지지 않았을 때 이행하는 promise 를 반환함
- promise 의 배열을 파라미터로 전달하면 결과값을 배열로 반환받게 된다.
사용하지 않을 때
const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)) } const getApple = async () => { await delay(1000); return '사과' } const getBanana = async () => { await delay(1000); return '바나나' } const pickFruits = async () => { const applePromise = getApple(); const bananaPromise = getBanana(); const apple = await applePromise; const banana = await bananaPromise; return `${apple} + ${banana}` } pickFruits().then(console.log)
사용했을 때const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)) } const getApple = async () => { await delay(1000); return '사과' } const getBanana = async () => { await delay(1000); return '바나나' } const pickFruits = async () => { return Promise.all([getApple(), getBanana()]) .then(fruits => fruits.join(' + ')) } pickFruits().then(console.log)
Promise.race()
배열에 전달받은 promise들 중에, 가장 먼저 실행되어야하는 promise의 결과값을 전달함
const delay = (ms) => {
return new Promise(resolve => setTimeout(resolve, ms))
}
const getApple = async () => {
await delay(3000);
return '사과'
}
const getBanana = async () => {
await delay(1000);
return '바나나'
}
const pickFruits = async () => {
return Promise.race([getApple(), getBanana()])
}
pickFruits().then(console.log)
=> 바나나