await의 기능은 promise가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않습니다.
await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법입니다. promise.then보다 가독성 좋고 쓰기도 쉽습니다.
then() 체이닝 처럼 비동기 처리 시 순서대로 처리됨을 보장하는 것과 같이 await도 마찬가지로 비동기 처리 시 순서대로 처리됨을 보장하는 것이다. 다만 동기적으로 보이기 때문에 이벤트 루프의 비동기 처리 순서에 혼동이 생길 수 있지만 기존 이벤트 루프의 비동기 처리 순서는 동일하다.
사용 가능 조건
async 가 선언된 함수 안에서만 사용이 가능하다.
Promise 객체를 반환하는 변수나 함수 앞에 선언하여 사용이 가능하다.
실행 기능
Promise가 fulfill 되거나 reject 될 때까지 async 함수의 실행을 일시 정지하고,
Promise가 fulfill되면 async 함수를 일시 정지한 부분부터 실행합니다.
이때 await 문의 반환 값은 Promise에서 fulfill된 값이 됩니다.
만약 Promise가 reject되면, await 문은 reject된 값을 throw 합니다.
await 연산자 다음에 나오는 문의 값이 Promise 가 아니면 해당 값을 resolved Promise로 변환 시킵니다. (Promise의 반환 값은 Promise 객체이기 때문이다.)
function delay(ms) {
// 시간을 지연시키고난 다음에 resolve를 호출하는데, 따로 resolve 값은 없다.
return new Promise((resolve) => setTimeout(resolve, ms));
}
async function getApple() {
await delay(1000); // await 은 async가 선언된 함수 안에서만 사용이 가능하다.
return 'apple'; // resolve 로 문자열 'apple' 을 넘기며 Promise<string> 객체를 반환한다.
}
// -> async function getApple 함수가 fulfill이 되거나, reject가 될 때까지
// await delay 함수가 완료가 될 때 까지 기다린다.
async function getBanana() {
await delay(1000); // await 은 async가 선언된 함수 안에서만 사용이 가능하다.
return 'banana'; // resolve 로 문자열 'banana' 을 넘기며 Promise<string> 객체를 반환한다.
}
// -> async function getBanana 함수가 fulfill이 되거나, reject가 될 때까지
// await delay 함수가 완료가 될 때 까지 기다린다.
// 아래처럼 작성되면 콜백지옥과 다름없다.
/**
function pickFruits() {
return getApple().then((apple) => {
return getBanana().then((banana) => `${apple} + ${banana}`);
});
}
*/
// 비동기 처리함수 getApple() 과 getBanana() 가 모두 완료된(fulfill) 다음에 같이 실행된다.
async function pickFruits() {
const apple = await getApple(); // apple 에는 Promise<string> 객체가 반환된다.
const banana = await getBanana(); // banana 에는 Promise<string> 객체가 반환된다.
console.log(apple);
return `${apple} + ${banana}`;
}
// async function pickFruits 함수가 fulfill 되거나 reject 가 될 때까지
// await 된 함수의 실행을 일시정지 한다.
// 비동기 처리함수 getApple() 과 getBanana() 가 모두 완료된(fulfill) 다음에 같이 실행된다.
pickFruits().then(console.log); // apple + banana
// useful Promise APIs
function pickAllFruits() {
return Promise.all([getApple(), getBanana()]).then(fruit =>
fruit.join(' + ') // 배열 형태로 받기 때문에 join() 함수가 가능하다.
);
}
// Promise API - all
// Promise 함수를 병렬로 동시에 실행되어 배열로 받아서 처리하는데,
// 값을 배열에 담아 배열형태로 값이 전달된다.
pickAllFruits().then((fruit) => console.log(`all: ${fruit}`));
// all: apple + banana
// useful Promise APIs
function pickOnlyOne() {
return Promise.race([getApple(), getBanana()]);
}
// Promise API - race
// Promise 함수 중에서 가장 먼저 실행되어 완료된 함수만을 배열로 받아서 처리하는데,
// 값을 배열에 담아 배열형태가 아닌 값으로 전달된다.
pickOnlyOne().then((fruit) => console.log(`race: ${fruit}`));
// race: apple