promise 를 통해 구현하게 되면 then을 통해서 계속해서 앞의 return값을 받아와야하기 때문에 명령이 길어지게 된다. async를 이용하면 함수안에 깔끔하게 담아서 정리가능하다. 우선 과일을 따는 함수를 만들어 보겠다.
// resolve 를 선언하기만 함.
function delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// 위의 코드는 아래의 코드와 같다. async 키워드는 자동으로 promise를 만들어준다.
async function delay(ms) {
return 'sucessfully resolved!'
}
// async는 뭐든지 prmomise를 return 하게한다.
//await는 async안에서만 쓸수 있으며 promise를 기다린다.
async function getApple() {
// delay를 통해 resolve가 성립이 되면 return 하도록 하는게 await키워드이다. then이랑 같은 역할을 한다고 보면 됨.
await delay(1000);
return "🍎";
}
async function getBanana() {
await delay(1000);
return "🍌";
}
그럼 이제 바나나와 사과 모두를 따는 함수를 만들어보자.
// 다시 콜백지옥이 떠오름. nesting이 중복되지 않도록 하는게 좋다 항상.
function pickFruits() {
return getApple().then((apple) => {
return getBanana.then((banana) => `${apple} + ${banana}`);
});
}
// async랑 await를 사용하면 앞서 then을 체이닝 한것과 같은 효과가 나타난다.
// 그래서 await하고 apple promise가 성공하면 banana로 넘어가는 것이다.
async function pickFruits() {
const apple = await getApple();
const banana = await getBanana();
return `${apple} + ${banana}`;
}
근데 사실상 apple과 banana는 서로 연계되어있는 작업이 아니라서 기다릴 필요없다. 그래서 동시에 실행되도록 하는게 더 빠르다.
async function pickFruitsFast() {
// promise 가 만들어지자 마자 실행되는 특성을 이용해서 병렬적으로 동시에 실행하도록 할 수 있다.
// 그래서 사과와 바나나를 동시에 딴다음 기다렸다가 출력하면 된다.
const applePromise = getApple();
const bananPromise = getBanana();
const apple = await applePromise;
const banana = await bananPromise;
return `${apple} + ${banana}`;
}
pickFruitsFast().then(console.log);
근데 이것 마저도 간단하게 만들수 있는 API가 있다. 바로 all 이라는 거다.
async function pickAllFruits() {
return Promise.all([getApple(), getBanana()]).then((fruits) =>
fruits.join(" + ")
);
}
pickAllFruits().then(console.log);
// 또는 둘중에 먼저 완료되는 것을 먼저 return 하는 API도 있다.
// 바로 race 라는 거다
async function pickFirstOne() {
return Promise.race([getApple(), getBanana()]);
}
pickFirstOne().then(console.log);
그럼. callback_to_promise 를 async와 await를 이용해서 refacotring 해보자
instagram 클론코딩하다가 geoLocation을 통해 위도와 경도를 가져오려다가 알게된 사실!
우선 코드부터!
async function getGeoLocation() {
return new Promise((res, rej) => {
navigator.geolocation.getCurrentPosition(res, rej);
});
}
우선 getCurrentPosition
에 들어가는 첫번째 인자는 자동으로 GeolocationPosition
이라는 객체를 받게 된다. 즉 res
함수는 GeolocationPosition
받게되고 이것을 promise객체안에 담아서 리턴하게 되는 것이다.
결국 정리하자면 res안에 인자로 들어가는 것이 성공적으로 불러올 경우 그것을 고대로 리턴하게 된다. 끝!