await의 기능은  promise가 처리되길 기다리는 동안엔 엔진이 다른 일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않습니다.

await는 promise.then보다 좀 더 세련되게 프라미스의 result 값을 얻을 수 있도록 해주는 문법입니다. promise.then보다 가독성 좋고 쓰기도 쉽습니다.

then() 체이닝 처럼 비동기 처리 시 순서대로 처리됨을 보장하는 것과 같이 await도 마찬가지로 비동기 처리 시 순서대로 처리됨을 보장하는 것이다. 다만 동기적으로 보이기 때문에 이벤트 루프의 비동기 처리 순서에 혼동이 생길 수 있지만 기존 이벤트 루프의 비동기 처리 순서는 동일하다.

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