Develop/Javascript
async와 await
윤태풍
2021. 2. 24. 21:50
async & await
-
프로미스 체이닝을 계속 하다보면 코드의 가독성이 떨어짐
-
async 와 await는 Promise를 간결/간편하고 동기적으로 실행되는것 처럼 보이게 만들어주는 API => 그렇다고 무조건 사용하는건 X
-
async 와 await는 기존에 존재하는 Promise 위에 조금 더 간편한 API를 제공함 이런 것을 syntactic sugar 라고 한다 (Class도 해당)
1. async
- 기존 방식
function fetchUser(){
//do network request in 10s..
return new Promise((resolve, reject)=>{
//return 'dada'; > promise가 pending 상태로 남아있게된다.
//***** executor 함수 안에선 꼭 resolve나 reject의 상태를 지정해줘야함 **********
resolve('dada'); // promise fullfiled 상태
// reject(new Error(`error`)); > 프로미스 rejected 상태
});
} //동기적으로 코드 수행하므로 10초동안 머물러서 기다리지 않게 하려 promise를 사용
- async 사용시 (내가 안써도 함수의 코드블록이 자동으로 Promise로 변환됨)
// 함수 선언식
async function fetchUser() {
return `dada`;
}
// 함수 표현식
const fetchUser = async function() {
return `dada`;
};
// 화살표 함수
const fetchUser = async () => {
return `dada`;
};
// fetchUser().then(data => console.log(data)); // 1. 함수로 바로 호출
const user = fetchUser(); // 2. 변수에 할당해서 호출
user.then(data => console.log(data));
console.log(user);
2. await
- 기존 방식
function delay(ms) {
return new Promise (resolve => setTimeout(resolve, ms));
}
function getApple() {
return delay(1000)
.then(() => `🍎`);
}
function getBanana() {
return delay(1000)
.then(() => `🍌`);
}
function pickFruits() {
return getApple()
.then(apple => {
return getBanana().then(banana => `${apple} + ${banana}`);
});
}
pickFruits().then(result => console.log(result));
==> chaining도 중첩적으로 많이 사용하게 되면 콜백지옥 비슷한걸 경험할수 있어😩😩
- await 사용시
- await는 async함수 내부에서만 사용가능
- 위의 방식처럼 chaining 하던 것을 동기적으로 쓰는 것처럼 await를 사용해 이해하기 쉽게 만들어 줄 수 있음
function delay(ms) {
return new Promise (resolve => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000);
// throw new Error(`error: apple`); > error 발생
return `🍎`;
}
async function getBanana() {
await delay(1000);
// throw new Error(`error: banana`);
return `🍌`;
}
- try catch 로 error 처리 가능
async function pickFruits(){
/*
let apple = null;
try {
apple = await getApple();
} catch(error) {
console.log(error);
}
let banana = null;
try {
banana = await getBanana();
} catch(error) {
console.log(error);
}
return `${apple} + ${banana}`;
apple과 banana는 서로 연관 없으므로 기다려줄 필요가 없음 밑에처럼 개선 가능
*/
// 위는 순차적인 실행 밑에는 병렬실행
const applePromise = getApple();
const bananaPromise = getBanana(); // 이때 만들자마자 바로 실행 (병렬실행 가능)
const apple = await applePromise();
const banana = await bananaPromise();
return `${apple} + ${banana}`;
}
pickFruits().then(console.log);
3. 유용한 Promise API
: 병령실행시 위의 코드는 좀 더러우므로 제공되는 Promise의 API로 깔끔하게 정리 O
function pickAllFruits(){
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join('+'));
}
//all을 써서 배열형태로 (getApple()..)전달->이 배열들의 것들을 다 받아서 배열로 다시 줌(fruit==> 'apple','banana')
//뽀너스) 배열에 있는 것들중 가장 먼저 도착하는 놈을 return
function pickOnlyOne(){
return Promise.race([getApple(), getBanana()]);
}