JavaScript & Node.js
#.14 비동기 [async, await]
Haksae
2022. 1. 9. 15:44
*Async & Await
- promise를 통해서 비동기적으로 처리하게되면 코드가 복잡해질 수 있는데,
- Async와 Await를 활용하면 promise를 간결하고 간편하고 동기적으로 실행하는 것처럼 보이게 한다 (syntactic sugar)
- 그렇다고 promise가 나쁘고 꼭 대체해야 되는 것은 아니다.
- promise를 유지해야 맞는 경우가 있고 async& await으로 바꿔줘야 하는 경우가 있다.
1. Async
- 동기 처리의 한계
function fetchUser(){
// do network request in 10 secs...
return 'haksae';
}
const user = fetchUser();
console.log(user);
- 이런 코드는 10초 정도 유저가 텅 빈 브라우저를 보기 때문에 비동기적으로 처리해야 한다.
- promise
- executor(resolve, reject) 콜백함수를 호출하지 않으면 아래와 pending 상태가 된다.
function fetchUser(){
return new Promise((resolve, reject)=>{
// do network request in 10 secs...
return 'haksae';
});
}
const user = fetchUser();
console.log(user);
- resolve, reject 호출
function fetchUser(){
return new Promise((resolve, reject)=>{
// do network request in 10 secs...
resolve('haksae');
});
}
const user = fetchUser();
user.then(console.log);
async function fetchUser(){
// do network request in 10 secs...
return 'haksae';
}
const user = fetchUser();
user.then(console.log);
console.log(user);
- async로 간단하게 변환
async function fetchUser() {
return "haksae";
}
const user = fetchUser();
user.then(console.log);
console.log(user);
2. await
- async가 붙은 함수 안에서만 사용가능
- chaining보다는 동기적인 것처럼 보이는 async사용 → 코드 쉽게 이해할 수 있음
function delay(ms){
return new Promise(resolve => setTimeout(resolve, ms));
}
async function getApple(){
await delay(3000);
return '🍎';
}
// chaining보다는 동기적인 것처럼 보이는 async사용
// 코드 쉽게 이해할 수 있음
// function getBanana(){
// return delay(3000)
// .then(()=>'🍌');
// }
async function getBanana(){
await delay(3000);
return '🍌';
}
// chaining > promise도 너무 중첩적으로 하면 콜백지옥과 비슷한 문제점 발생
function pickFruits(){
return getApple()
.then(apple => {
return getBanana()
.then(banana => `${apple} + ${banana}`);
})
}
pickFruits().then(console.log);
//* async 사용하여 해결
// 코드를 작성이 동기적인 방식으로 하는 것처럼 쓰고 리턴값도 있어 간편
async function pickFruits(){
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
pickFruits().then(console.log);
3. await 병렬 처리
- 동시다발적으로 수행 가능한 코드를 병렬적으로 처리
async function pickFruits(){
//병렬 처리
const applePromise = getApple(); // 1초
const bananaPromise = getBanana(); // 1초
// 총 1초
const apple = await applePromise;
const banana = await bananaPromise;
return `${apple} + ${banana}`;
- 그러나 병렬 처리가 가능한 상황에서는 promise API를 통해서 더 꺠끗하게 코드 작성 가능
- promise.all()
- promise배열을 전달하면 모든 promise들이 병렬적으로 다 받을 때까지 모아준다.
- all<T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>;
function picKAllFruits(){
return Promise.all([getApple(), getBanana()])
.then(fruits => fruits.join(' + '));
}
picKAllFruits().then(console.log);
- promise.race()
- 비동기 처리중 가장 먼저 리턴되는 promise 배열을 출력한다
- race<T>(values: readonly T[]): Promise<T extends PromiseLike<infer U> ? U : T>;
function pickOnlyOne(){
return Promise.race([getApple(), getBanana()]);
}
pickOnlyOne().then(console.log);
출처 : 드림코딩엘리 https://www.youtube.com/channel/UC_4u-bXaba7yrRz_6x6kb_w